#include <string.h>
#include <stdlib.h>
+void encode_hex(const char* src_bytes, int src_size, char* dest) {
+ const char hex[17] = "0123456789abcdef";
+ int i;
+ for (i=0; i<src_size; i++) {
+ *dest++ = hex[(src_bytes[i] & 0xF0) >> 4];
+ *dest++ = hex[src_bytes[i] & 0x0F];
+ }
+ *dest = 0;
+}
+
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 values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 255};
const char ILLEGAL_CHAR = 255;
int i;
- char conversion[256] = { ILLEGAL_CHAR };
- for (i=0; i<sizeof(valid_chars); i++) {
+ char conversion[256];
+ for (i=0; i<256; i++)
+ conversion[i] = ILLEGAL_CHAR;
+ for (i=0; i<sizeof(valid_chars)-1; 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;
+ if (conversion[*srcp++] == ILLEGAL_CHAR)
+ return 0;
srcp = src;
*destlen = 0;
if (strlen(src)%2) {
*dest++ = conversion[*srcp++];
- *destlen++;
+ (*destlen)++;
}
- while (*(src+2) != 0) {
- *dest = conversion[*srcp]*256 + conversion[*(srcp+1)];
+ while (*srcp != 0) {
+ *dest++ = (conversion[*srcp]<<4) | conversion[*(srcp+1)];
srcp += 2;
- *destlen++;
+ (*destlen)++;
}
return 1;
}
+void encode_base64(const char* src_bytes, int src_size, char* dest) {
+ const char conversion[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ const char padding = ' ';
+ char* srcp = src_bytes;
+ while(src_size >= 3) { // 3 bytes = 24 bits = 4 output
+ dest[0] = conversion[(srcp[0] & 0xFC) >> 2];
+ dest[1] = conversion[(srcp[0] & 0x03) << 4 | (srcp[1] & 0xF0) >> 4];
+ dest[2] = conversion[(srcp[1] & 0x0F) << 2 | (srcp[2] & 0xC0) >> 6];
+ dest[3] = conversion[ srcp[2] & 0x3F];
+ srcp+=3;
+ dest+=4;
+ src_size-=3;
+ }
+ if (src_size == 2) {
+ dest[0] = conversion[(srcp[0] & 0xFC) >> 2];
+ dest[1] = conversion[(srcp[0] & 0x03) << 4 | (srcp[1] & 0xF0) >> 4];
+ dest[2] = conversion[(srcp[1] & 0x0F) << 2];
+ dest[3] = padding;
+ dest+=4;
+ } else if (src_size == 1) {
+ dest[0] = conversion[(srcp[0] & 0xFC) >> 2];
+ dest[1] = conversion[(srcp[0] & 0x03) << 4];
+ dest[2] = padding;
+ dest[3] = padding;
+ dest+=4;
+ }
+ *dest = 0;
+}
+
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++) {
+ char conversion[256];
+ for (i=0; i<256; i++)
+ conversion[i] = 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
+ if (strlen(src)%4) { printf("Strings must be padded to a multiple of 4 bytes\n"); 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;
+ *(src+3) == 0) { printf("Strings must be padded to a multiple of 4 bytes\n"); return 0; }
if (*src == padding || *(src+1) == padding) return 0;
if (*(src+2) == padding) {
+ printf("2 padding\n");
// 2 padding characters
if(*(src+3) != padding) return 0;
if(*(src+4) != 0) return 0;
conversion[*(src+1)] == ILLEGAL_CHAR) return 0;
if (conversion[*(src+2)] & 0x0F != 0) return 0;
- *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+ dest[0] = (conversion[*src] & 0xFF) << 2 | (conversion[*(src+1)] & 0x30) >> 4;
+ *destlen+=1;
return 1;
} else if (*(src+3) == padding) {
+ printf("1 padding\n");
// 1 padding character
if(*(src+4) != 0) return 0;
if (conversion[*src] == 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);
+ dest[0] = (conversion[*src] & 0xFF) << 2 | (conversion[*(src+1)] & 0x30) >> 4;
+ dest[1] = (conversion[*(src+1)] & 0x0F) << 4 | (conversion[*(src+2)] & 0x3C) >> 2;
+ *destlen+=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)];
+ dest[0] = (conversion[*src] & 0x3F) << 2 | (conversion[*(src+1)] & 0x30) >> 4;
+ dest[1] = (conversion[*(src+1)] & 0x0F) << 4 | (conversion[*(src+2)] & 0x3C) >> 2;
+ dest[2] = (conversion[*(src+2)] & 0x03) << 6 | (conversion[*(src+3)] & 0x3F);
+ src+=4;
+ dest+=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;
-}
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;
+ char expected_bytes[] = {0x49, 0x27, 0x6d, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x73, 0x6f, 0x6e, 0x6f, 0x75, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x68, 0x72, 0x6f, 0x6f, 0x6d};
+ char expected_base64[] = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t";
+
+ char bytes[sizeof(sample_hex)];
+ int bytes_size;
if (!decode_hex(sample_hex, bytes, &bytes_size)) {
- printf("Decode hex failed");
+ printf("Decode hex failed\n");
exit(1);
}
+ if (bytes_size != sizeof(expected_bytes)) {
+ printf("Decode hex wrong size %d\n", bytes_size);
+ exit(1);
+ }
+ if (memcmp(bytes, expected_bytes, bytes_size) == 0) {
+ printf("Decode hex: success\n");
+ } else {
+ printf("Decode hex: failure\n");
+ }
+
+ char reencoded_hex[sizeof(sample_hex)];
encode_hex(bytes, bytes_size, reencoded_hex);
if (strcmp(sample_hex, reencoded_hex) == 0) {
- printf("hex decode/encode: success");
+ printf("Encode hex: success\n");
} else {
- printf("Expected %s\n Got: %s", sample_hex, reencoded_hex);
+ printf("Encode hex: failure\n");
+ printf("Expected %s\n Got: %s\n", sample_hex, reencoded_hex);
+ exit(1);
}
- 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");
+ if (strcmp(base64,expected_base64) == 0) {
+ printf("Base64 encode: success\n");
} else {
- printf("Expected: %s\n Got: %s", expected_base64, base64);
+ printf("Base64 encode: failure\n");
+ printf("Expected: %s\n Got: %s\n", expected_base64, base64);
exit(1);
}
+ char decoded_bytes[sizeof(sample_hex)];
+ int decoded_bytes_size;
if (!decode_base64(base64, decoded_bytes, &decoded_bytes_size)) {
- printf("Decode base64 failed");
+ printf("Decode base64 failed\n");
exit(1);
}
if (bytes_size == decoded_bytes_size && memcmp(bytes, decoded_bytes, bytes_size) == 0) {
- printf("Base64 decode: success");
+ printf("Base64 decode: success\n");
} else {
- printf("Base64 decode is wrong");
+ printf("Base64 decode is wrong\n");
exit(1);
}