Я работал над реализацией декодера base64 в C. Я читал об конвертации base64 в таких местах, как Wikipedia page, а также с помощью онлайн converters для проверки моей работы. Кажется прямолинейным: просто замените каждый символ base64 на соответствующую 6-битную двоичную строку!C: Base 64 to двоичное преобразование
My Base64-to-binary decoding является правильным, если строка 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 нет?
Каждый случай, который вы предоставили, имеет смысл. Не могли бы вы объяснить пример 3 в моем примере? Первые 10 символов Base64 отлично кодируют 10 * 6 бит = 60 бит, что по-прежнему составляет 4 бита, равных 8 байтам, поэтому я понимаю, что нам нужно еще 4 бита. Тем не менее, 11-й символ Base64, '+', задается в двоичном формате как «111110» - 5 бит без 0-х - кажется, нам нужно 65 бит для кодирования этой строки. Вы можете это объяснить? Как бы выглядело преобразование для kNSHd94m7d + = vs. kNSHd94m7d8 = и почему? – Matt
@Matt правильный кодировщик Base64 не будет генерировать 'kNSHd94m7d + ='. Строгий декодер отклонил бы его как недействительный; прощающий будет декодировать его так же, как 'kNSHd94m7d8 ='. – hobbs
(только 'A',' Q', 'g' или' w' должны предшествовать '==' и только 'A',' E', 'I',' M', 'Q',' U ',' Y', 'c',' g', 'k',' o', 's',' w', '0',' 4' или '8' должны предшествовать' = 'в правильном Base64 .) – hobbs