我一直在努力在C中实现base64解码器。我一直在维基百科page等地方阅读base64转换,并使用在线converters检查我的工作。看起来很简单:只需用相应的6位二进制字符串替换每个base64字符!
我的Base64到二进制解码是正确的,只要要解码的base64字符串是4的倍数。如果字符串长度不是4的倍数,或者存在填充等号,我的代码不会匹配在线转换器的结果。
我以为我理解了填充 - 只需替换' ='带零的字符(6位,6位)。但是,在使用转换器时,我仍然无法匹配转换器的结果。
以下是我写的代码:
int main(void){
printf("Testing b642bin ...\n\n");
printf("Case 1: Converting 'AA==' to bin:\n");
printf("Expected Result: 000000000000000000000000\n");
printf("Actual Result: %s\n\n", b642bin("AA=="));
printf("Case 2: Converting '+aHg' to bin:\n");
printf("Expected Result: 111110011010000111100000\n");
printf("Actual Result: %s\n\n", b642bin("+aHg"));
printf("Case 3: Converting 'kNSHd94m7d+=' to bin:\n");
printf("Expected Result: 1001000011010100100001110111011111011110001001101110110111011111\n");
printf("Actual Result: %s\n\n", b642bin("kNSHd94m7d+="));
return 0;
}
char bin6_table[65][7] = {"000000", "000001", "000010", "000011", "000100",
"000101","000110", "000111", "001000", "001001",
"001010", "001011", "001100", "001101", "001110",
"001111", "010000", "010001", "010010", "010011",
"010100", "010101", "010110", "010111", "011000",
"011001", "011010", "011011", "011100", "011101",
"011110", "011111", "100000", "100001", "100010",
"100011", "100100", "100101", "100110", "100111",
"101000", "101001", "101010", "101011", "101100",
"101101", "101110", "101111", "110000", "110001",
"110010", "110011", "110100", "110101", "110110",
"110111", "111000", "111001", "111010", "111011",
"111100", "111101", "111110", "111111", "000000"};
char base64_table[65] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/','='};
char* b64Char2bin(char b64){
int n = 64;
int k;
char *bin;
for(k=0;k<n;k++){
if (b64 == base64_table[k]) {
bin = bin6_table[k];
break;
}
}
return bin;
}
char* b642bin(char *b64_str) {
int i;
size_t len = strlen(b64_str);
char* bin_str = (char*)malloc(((len * 6) + 1) * sizeof(char));
for (i = 0; i < (int)len; i++) {
const char* binSextet = b64Char2bin(b64_str[i]);
memcpy(&bin_str[6*i], binSextet,7);
}
return bin_str;
}
输出如下:
测试b642bin ...
Case 1: Converting 'AA==' to bin:
Expected Result: 000000000000000000000000
Actual Result: 000000000000000000000000
Case 2: Converting '+aHg' to bin:
Expected Result: 111110011010000111100000
Actual Result: 111110011010000111100000
Case 3: Converting 'kNSHd94m7d+=' to bin:
Expected Result: 1001000011010100100001110111011111011110001001101110110111011111
Actual Result: 100100001101010010000111011101111101111000100110111011011101111110000000
如果我提供的转换器是正确的,我不了解Base64。显然,您不能简单地用相应的6位二进制替换每个字符。为什么案例1和案例2是正确的,但案例3不是?
答案 0 :(得分:0)
字节(嗯,八位字节,如果你想获得所有技术)是8位长。 Base64一次编码6位。当编码的字节数不是的三倍时使用填充,因此位数不是的六倍。使用填充解码base64时,不输出 more 零位,输出 less 位以产生正确的字节数。
作为一个具体的例子:
Base64:////
二进制:11111111 11111111 11111111
Base64://8=
二进制:11111111 11111111
Base64:/w==
二进制:11111111