Hex для base64 на *nix
Примечание: я пометил этот вопрос как дубликат другого вопроса. Но я все же сохраняю это, поскольку у него есть пример и четко объясненный ответ, так что, надеюсь, это должно помочь другим.
- Мне нужно преобразовать строку шестнадцатеричных символов в base64, как это делает этот онлайн-конвертер в *nix.
За "5C78336D77D8DF448007D277DAD5C569
"(Hex) Я знаю, ожидаемый результат"XHgzbXfY30SAB9J32tXFaQ==
"(Base64).
Но когда я пытаюсь преобразовать его в двоичный файл, а затем base64, я получаю это:
[kent@server SrcFiles]$ echo "5C78336D77D8DF448007D277DAD5C569" | xxd -b
0000000: 00110101 01000011 00110111 00111000 00110011 00110011 5C7833
0000006: 00110110 01000100 00110111 00110111 01000100 00111000 6D77D8
000000c: 01000100 01000110 00110100 00110100 00111000 00110000 DF4480
0000012: 00110000 00110111 01000100 00110010 00110111 00110111 07D277
0000018: 01000100 01000001 01000100 00110101 01000011 00110101 DAD5C5
000001e: 00110110 00111001 00001010 69.
[kent@server SrcFiles]$ echo "001101010100001100110111001110000011001100110011001101100100010000110111001101110100010000111000010001000100011000110100001101000011100000110000001100000011011101000100001100100011011100110111010001000100000101000100001101010100001100110101001101100011100100001010" | base64
MDAxMTAxMDEwMTAwMDAxMTAwMTEwMTExMDAxMTEwMDAwMDExMDAxMTAwMTEwMDExMDAxMTAxMTAw
MTAwMDEwMDAwMTEwMTExMDAxMTAxMTEwMTAwMDEwMDAwMTExMDAwMDEwMDAxMDAwMTAwMDExMDAw
MTEwMTAwMDAxMTAxMDAwMDExMTAwMDAwMTEwMDAwMDAxMTAwMDAwMDExMDExMTAxMDAwMTAwMDAx
MTAwMTAwMDExMDExMTAwMTEwMTExMDEwMDAxMDAwMTAwMDAwMTAxMDAwMTAwMDAxMTAxMDEwMTAw
MDAxMTAwMTEwMTAxMDAxMTAxMTAwMDExMTAwMTAwMDAxMDEwCg==
Может кто-то указать мне верное направление?
2 ответа
Если вы хотите использовать xxd
чтобы декодировать вашу шестнадцатеричную строку, вам нужно использовать xxd -r -p
, И, таким образом, вы получаете:
echo "5c78336d77d8df448007d277dad5c569" | xxd -r -p | base64
XHgzbXfY30SAB9J32tXFaQ==
-r
для обратного, так что xxd
расшифрует ваш шестнадцатеричный дамп, и -p
означает, что входные данные являются простым дампом (то есть неокрашенной шестнадцатеричной строкой) без форматирования, такого как номер строки (строк).
Это продолжение комментариев в оригинальном вопросе. Это закончилось намного дольше, чем я ожидал; Итак, перенесли его в раздел ответов.
bc
является числовым процессором, способным работать с любой произвольной базой; однако из Руководства по эксплуатации bc:
Для баз больше 16,
bc
использует метод многосимвольных цифр для печати чисел, где каждая старшая базовая цифра печатается как базовая цифра 10. Многосимвольные цифры разделены пробелами.
(Аналогичное утверждение появляется на странице руководства bc.)
То, что мы называем "base64", является специальным назначением символов каждому из 64 значений. (См. Статью в Википедии о Base64.)
Представление "0" bc
будет "0"; тогда как фактическая base64- "A".
Вывод вашей предложенной команды bc:
$ echo "obase=64; ibase=16; 5C78336D77D8DF448007D277DAD5C569" | bc
01 28 30 03 13 45 29 61 35 31 17 08 00 07 52 39 31 26 53 28 21 41
Так что если bc
выходы 01 28 30 03 . . .
почему мы не можем просто посмотреть значения для 01, 28, 30 и т. д. в таблице (получая "B", "c" и "e"; это отличается от "XHg...", который вы ожидать)?
Во-первых, давайте упростим проблему.
Если мы кормим более короткую строку в bc
, например, только первые 2,5 байта, вывод выглядит аналогично:
$ echo "obase=64; ibase=16; 5C783" | bc
01 28 30 03
Но еще более короткая строка совершенно другая:
$ echo "obase=64; ibase=16; 5C78" | bc
05 49 56
Это почему? Ваша исходная строка состояла из 32 символов (2^4*32; 2^128), что для деления на 64 (2^6) требуется 22 символа (22*6=132), а оставшиеся четыре. Этот остаток важен при рассмотрении вывода bc
но не для чего-то еще.
Строка ввода из 4 символов имеет 2^16 значений. Разделенный на 64 (2^6), он может уместиться в три 64-битных слова (с оставшимися 2 битами); но входная строка из 5 символов имеет 2^20 значений и разделена на 2^6, для отображения требуется четыре слова (с оставшимися четырьмя битами; тот же остаток, что и в исходной строке).
Еще более короткое входное значение (5C) также имеет тот же остаток (2^8 / 2^6 = 2 + 4 бита)
$ echo "obase=64; ibase=16; 5C" | bc
01 28
Итак, используя эту "особенность" bc
мы можем использовать первые два символа, чтобы разработать простое описание того, что на самом деле происходит.
5C
в двоичном есть 01011100
, В мире base64 мы смотрим на первые 6 бит (010111
или десятичное 23) и увидеть в таблице википедии, 23 на самом деле X
, Большой! Это соответствует тому, что вы ожидаете! Затем мы продолжим через строку, шесть битов за раз.
В bc, с другой стороны, откуда берется 01 28? Вернуться к двоичному 01011100
, В отличие от процедуры base64, которая начинается в начале строки и дополняется "=" до конца, если есть остаток (число символов base16 не кратно 3), bc дополняет 0 до начала входное значение. Таким образом, с вышеупомянутым остатком 4, bc фактически будет работать с 0000 01011100
; и в 6-битных блоках (base64) это заканчивается как 000001 011100
или десятичные значения 01 и 28.
Кстати, если вы добавите конец входной строки в bc так, чтобы ее длина была кратна трем, вы получите нечто, похожее на желаемый результат:
$ echo "obase=64; ibase=16; 5C78336D77D8DF448007D277DAD5C5690" | bc
23 07 32 51 27 23 31 24 55 52 18 00 01 61 09 55 54 45 23 05 26 16
Вам все еще нужно искать 23= X
07= H
32= g
и т. д., в таблице.