cryptopals_c

cryptopals crypto challenges solutions in pure c
git clone git://git.superpozycja.net/cryptopals_c
Log | Files | Refs | README

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 }