Это продолжение комментариев в оригинальном вопросе. Это закончилось намного дольше, чем я ожидал; Итак, перенесли его в раздел ответов.
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
и т. Д. В таблице.