util.c (1796B)
1 #include "util.h" 2 3 const char b64table[] = 4 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 5 6 static int b64_chunk_to_hex(char **hex, char *b64) 7 { 8 unsigned int val; 9 unsigned int sz; 10 unsigned int i; 11 12 if (strlen(b64) != 4) 13 return -1; 14 15 val = 0; 16 for (i = 0; i < 4; i++) { 17 int j = 0; 18 val <<= 6; 19 20 while (b64[i] != '=' && b64table[j] != b64[i]) 21 j++; 22 23 val += j; 24 } 25 26 sz = 6 - 2 * ((b64[2] == '=') + (b64[3] == '=')); 27 sz++; 28 29 *hex = (char *) malloc(sizeof(char) * sz); 30 snprintf(*hex, sz, "%0*x", sz - 1, val); 31 return 0; 32 } 33 34 int base64_to_hex(char **hex, char *b64) 35 { 36 unsigned int len; 37 38 len = (strlen(b64) * 3 / 4) + 2; 39 *hex = (char *) malloc(sizeof(char *) * len); 40 41 for (int i = 0; i < strlen(b64)/4; i++) { 42 char b64_chunk[5]; 43 char *hex_chunk; 44 45 b64_chunk[4] = '\0'; 46 memcpy(b64_chunk, b64+4*i, 4); 47 b64_chunk_to_hex(&hex_chunk, b64_chunk); 48 strcat(*hex, hex_chunk); 49 } 50 } 51 52 int hex_to_base64(char **b64, char *hex) 53 { 54 int leftover_length; 55 int block_count; 56 int res_length; 57 int length; 58 char *res; 59 int i; 60 61 length = strlen(hex); 62 block_count = length / 6; 63 leftover_length = length % 6; 64 res_length = block_count * 4; 65 66 if (leftover_length%2 == 1) { 67 fprintf(stderr, "bad sequence length\n"); 68 return -1; 69 } 70 71 res = (char *) malloc(sizeof(char) * res_length + 2); 72 73 for (i = 0; i < block_count + (leftover_length != 0); i++) { 74 char block[6+1]; 75 int block_hex; 76 int end_ix; 77 int j; 78 79 end_ix = i < block_count ? 6 : leftover_length; 80 memcpy(block, hex+(6*i), end_ix); 81 block[end_ix] = '\0'; 82 83 block_hex = strtol(block, NULL, 16); 84 block_hex <<= 4 * (6 - end_ix); 85 86 for (j = 0; j < 4; j++) { 87 char b64; 88 89 b64 = b64table[(block_hex >> 6 * (3 - j)) & 0x3f]; 90 res[4 *i + j] = j <= end_ix / 2 ? b64 : '='; 91 } 92 } 93 94 *b64 = res; 95 return 0; 96 }