Hex для base64 на * nix

2457
Kent Pawar

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

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

Может кто-то указать мне верное направление?

1
Преобразование значения Base 16 в двоичное число сохранит его в Base 16. Вам необходимо преобразовать Base 16 в Base 64, а затем преобразовать его в двоичное. Об этом спрашивали и отвечали раньше http://superuser.com/questions/158142/how-can-i-convert-from-hex-to-base64?rq=1 Ramhound 11 лет назад 1
@Ramhound - Спасибо. Я попытался `echo 'obase = 10; ibase = 16;` cat in.dat` "| до н. base64> out.dat` и `echo" obase = 64; ibase = 16; `cat in.dat`" | bc`. Не могли бы вы дать мне несколько советов, где я иду не так ..? Kent Pawar 11 лет назад 0
Ваш синтаксис неверен. Посмотрите правильный синтаксис. Ramhound 11 лет назад 0
В качестве комментария к исходному вопросу, `echo" 0011010 ... "| base64` не отправляет двоичную строку 0011010 ... но, строку символов ascii 0 и ascii 1. Вот почему ваш результат не соответствует вашим ожиданиям. Kent 11 лет назад 1
Спасибо @Kent! Хорошо. Но тогда разве это не должно работать? `echo" obase = 64; ibase = 16; 5C78336D77D8DF448007D277DAD5C569 "` # Скажите `bc` принять входную строку ASCII в виде шестнадцатеричного представления и преобразовать ее в base64. Kent Pawar 11 лет назад 0
bc тоже не делает то, что вы ожидаете. Что касается числового процессора, его значение для 0, 1, 2 в base 64 по-прежнему равно 0, 1, 2. Однако кодирование base64 для 0 - это A, 1 = B, 2 = C и т. Д. Это произвольно; и, поскольку `bc` является калькулятором, он не сделает это произвольное преобразование для нас. У меня есть еще кое-что сказать по этому поводу, но это требует форматирования и гораздо больше, чем 512 символов. Я добавлю его в раздел ответов ниже, даже если он не отвечает на ваш первоначальный вопрос. Kent 11 лет назад 1

2 ответа на вопрос

6
Levans

If you want to use xxd to decode your hex string, you need to use xxd -r -p. And thus, you get:

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

-r is for reverse, so that xxd will decode your hex dump, and -p is to say that the input is a plain dump (i.e., an unadorned hex string), with no formatting such as line-number(s).

Вы можете получить тот же результат, используя метод грубой силы: `` printf "\ x5C \ x78 \ x33 \ x6D \ x77 \ xD8 \ xDF \ x44 \ x80 \ x07 \ xD2 \ x77 \ xDA \ xD5 \ xC5 \ x69" | base64``. Scott 6 лет назад 0
2
Kent

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

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

+1. Забыл поблагодарить вас за это. Это довольно подробно и полезно. Kent Pawar 10 лет назад 0