1

Примечание: я пометил этот вопрос как дубликат другого вопроса. Но я все же сохраняю это, поскольку у него есть пример и четко объясненный ответ, так что, надеюсь, это должно помочь другим.

- Мне нужно преобразовать строку шестнадцатеричных символов в 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 ответа2

6

Если вы хотите использовать xxd для декодирования вашей шестнадцатеричной строки, вам нужно использовать xxd -r -p . И, таким образом, вы получаете:

echo "5c78336d77d8df448007d277dad5c569" | xxd -r -p | base64
XHgzbXfY30SAB9J32tXFaQ==

-r для обратного, так что xxd будет декодировать ваш шестнадцатеричный дамп, а -p означает, что ввод является простым дампом (то есть неокрашенной шестнадцатеричной строкой), без форматирования, такого как номер строки (строк).

2

Это продолжение комментариев в оригинальном вопросе. Это закончилось намного дольше, чем я ожидал; Итак, перенесли его в раздел ответов.

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 и т.д. В таблице.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .