--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int decode_hex(char* src, char* dest, int *destlen) {
+ // Returns 1 for success, 0 for failure
+ const char valid_chars[] ="0123456789aAbBcCdDeEfF";
+ const char values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+ const char ILLEGAL_CHAR = 255;
+ int i;
+ char conversion[256] = { ILLEGAL_CHAR };
+ for (i=0; i<sizeof(valid_chars); i++) {
+ conversion[valid_chars[i]] = values[i];
+ }
+
+ char* srcp = src;
+ // Check for non-hex characters
+ while (*srcp != 0)
+ if (conversion[*srcp++] == ILLEGAL_CHAR) return 0;
+ srcp = src;
+ *destlen = 0;
+ if (strlen(src)%2) {
+ *dest++ = conversion[*srcp++];
+ *destlen++;
+ }
+ while (*(src+2) != 0) {
+ *dest = conversion[*srcp]*256 + conversion[*(srcp+1)];
+ srcp += 2;
+ *destlen++;
+ }
+ return 1;
+}
+
+int decode_base64(char* src, char* dest, int* destlen) {
+ char base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ const char ILLEGAL_CHAR = 255;
+ const char padding = '=';
+ int i;
+ char conversion[256] = {ILLEGAL_CHAR};
+ for (i=0; i<64; i++) {
+ conversion[base64[i]] = i;
+ }
+
+ if (strlen(src)%4) return 0; // We can't deal with strings unless they are padded
+
+ // Decode
+ *destlen=0;
+ while(*src != 0) {
+ if (*(src+1) == 0 ||
+ *(src+2) == 0 ||
+ *(src+3) == 0) return 0;
+ if (*src == padding || *(src+1) == padding) return 0;
+ if (*(src+2) == padding) {
+ // 2 padding characters
+ if(*(src+3) != padding) return 0;
+ if(*(src+4) != 0) return 0;
+ if (conversion[*src] == ILLEGAL_CHAR ||
+ conversion[*(src+1)] == ILLEGAL_CHAR) return 0;
+ if (conversion[*(src+2)] & 0x0F != 0) return 0;
+
+ *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+ return 1;
+ } else if (*(src+3) == padding) {
+ // 1 padding character
+ if(*(src+4) != 0) return 0;
+ if (conversion[*src] == ILLEGAL_CHAR ||
+ conversion[*(src+1)] == ILLEGAL_CHAR ||
+ conversion[*(src+2)] == ILLEGAL_CHAR) return 0;
+ if (conversion[*(src+2)] & 0x03 != 0) return 0;
+
+ *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+ *dest++ = (conversion[*(src+1)] & 0x0F) + (conversion[*(src+2)] & 0x3C >> 2);
+ return 1;
+ } else {
+ // 0 padding characters
+ *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+ *dest++ = (conversion[*(src+1)] & 0x0F) + (conversion[*(src+2)] & 0x3C >> 2);
+ *dest++ = (conversion[*(src+2)] & 0x03) + conversion[*(src+3)];
+ *destlen+=3;
+ }
+ }
+ *dest=0;
+ return 1;
+}
+
+void encode_base64(const char* src_bytes, int src_size, char* dest) {
+ const char conversion[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ const char padding = ' ';
+ const char* srcp = src_bytes;
+ while(src_size > 3) { // 3 bytes = 24 bits = 4 output
+ *dest++ = conversion[src_bytes[0] & 0xFC];
+ *dest++ = conversion[(src_bytes[0] << 6) + src_bytes[1] & 0xF0];
+ *dest++ = conversion[(src_bytes[1] << 4) + src_bytes[2] & 0xC0];
+ *dest++ = conversion[(src_bytes[2] << 2)];
+ src_bytes+=3;
+ src_size-=3;
+ }
+ if (src_size == 2) {
+ *dest++ = conversion[src_bytes[0] & 0xFC];
+ *dest++ = conversion[(src_bytes[0] << 6) + src_bytes[1] & 0xF0];
+ *dest++ = conversion[(src_bytes[1] << 4)];
+ *dest++ = padding;
+ } else if (src_size == 1) {
+ *dest++ = conversion[src_bytes[0] & 0xFC];
+ *dest++ = conversion[(src_bytes[0] << 6)];
+ *dest++ = padding;
+ *dest++ = padding;
+ }
+ *dest = 0;
+}
+
+void encode_hex(const char* src_bytes, int src_size, char* dest) {
+ char hex[17] = "0123456789ABCDEF";
+ int i;
+ for (i=0; i<src_size; i++) {
+ *dest++ = hex[src_bytes[src_size] & 0xF0];
+ *dest++ = hex[src_bytes[src_size] & 0x0F];
+ }
+ *dest = 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "io.h"
+
+int main() {
+ char sample_hex[] = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
+ char reencoded_hex[sizeof(sample_hex)*2];
+ char bytes[sizeof(sample_hex)], decoded_bytes[sizeof(sample_hex)];
+ int bytes_size, decoded_bytes_size;
+ if (!decode_hex(sample_hex, bytes, &bytes_size)) {
+ printf("Decode hex failed");
+ exit(1);
+ }
+ encode_hex(bytes, bytes_size, reencoded_hex);
+ if (strcmp(sample_hex, reencoded_hex) == 0) {
+ printf("hex decode/encode: success");
+ } else {
+ printf("Expected %s\n Got: %s", sample_hex, reencoded_hex);
+ }
+
+ char expected_base64[] = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t";
+ char base64[sizeof(sample_hex)*4/3+5];
+ encode_base64(bytes, bytes_size, base64);
+ if (strcmp(base64,expected_base64)) {
+ printf("Base64 encode: success");
+ } else {
+ printf("Expected: %s\n Got: %s", expected_base64, base64);
+ exit(1);
+ }
+
+ if (!decode_base64(base64, decoded_bytes, &decoded_bytes_size)) {
+ printf("Decode base64 failed");
+ exit(1);
+ }
+ if (bytes_size == decoded_bytes_size && memcmp(bytes, decoded_bytes, bytes_size) == 0) {
+ printf("Base64 decode: success");
+ } else {
+ printf("Base64 decode is wrong");
+ exit(1);
+ }
+
+}