Esta é uma continuação dos comentários na pergunta original. Acabou por muito mais tempo do que eu esperava; então, movido para a seção de respostas.
bc
é um processador numérico capaz de lidar com qualquer base arbitrária; no entanto, do Manual de comando da bc :
For bases greater than 16, bc
uses a multi-character digit method of
printing the numbers where each higher base digit is printed as a base
10 number. The multi-character digits are separated by spaces.
(Uma declaração semelhante aparece na página man bc .)
O que chamamos de "base64" é uma atribuição especial de caracteres para cada um dos 64 valores. (Veja o artigo da Wikipedia sobre Base64 .)
A representação de "0" por bc
seria "0"; enquanto que a base64 é "A".
A saída do seu comando bc sugerido é:
$ 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
Então, se bc
produz 01 28 30 03 . . .
, por que não podemos simplesmente procurar o
valores para 01, 28, 30, etc., na tabela (produzindo "B", "c" e "e";
que é diferente do "XHg…" que você espera)?
Primeiro, vamos simplificar o problema.
Se alimentarmos uma string mais curta em bc
, como apenas os primeiros 2.5 bytes, a saída será semelhante:
$ echo "obase=64; ibase=16; 5C783" | bc
01 28 30 03
Mas, uma string ainda mais curta é completamente diferente:
$ echo "obase=64; ibase=16; 5C78" | bc
05 49 56
Por que isso? Sua string original tinha 32 caracteres, (2 ^ 4 * 32; 2 ^ 128), que divididos em 64 (2 ^ 6) requer 22 caracteres (22 * 6 = 132), com um resto de quatro. Esse restante é importante quando se olha para a saída de bc
, mas não para qualquer outra coisa.
A string de entrada de 4 caracteres tem 2 ^ 16 valores. Dividido por 64 (2 ^ 6), pode caber em três palavras de 64 bits (com 2 bits restantes); mas, a string de entrada de 5 caracteres tem 2 ^ 20 valores e dividida por 2 ^ 6, ela requer quatro palavras para exibir (com quatro bits sobrando; o mesmo restante da string original).
Um valor de entrada ainda menor (5C) também tem o mesmo resto (2 ^ 8/2 ^ 6 = 2 + 4 bits)
$ echo "obase=64; ibase=16; 5C" | bc
01 28
Então, usando esse "recurso" de bc
, podemos usar os dois primeiros caracteres para desenvolver uma descrição simples do que realmente está acontecendo.
5C
no binário é 01011100
. No mundo base64, nós olhamos os primeiros 6 bits ( 010111
, ou decimal 23) e vemos na tabela wikipedia, 23 é na verdade X
. Ótimo! Corresponde ao que você espera! Continuaríamos então através da corda, seis bits de cada vez.
Em bc, por outro lado, de onde vem o 01 28? De volta ao binário 01011100
. Ao contrário do procedimento base64, que começa no início da string e preenche "=" até o final, se houver um resto (o número de caracteres base16 não é um múltiplo de 3), acelera 0s até o início de o valor de entrada. Então, com o restante de 4, bc vai funcionar com 0000 01011100
; e, em pedaços de 6 bits (base64), isso acaba em 000001 011100
, ou os valores decimais de 01 e 28.
A propósito, se você preencher o final da string de entrada para bc para que seu tamanho seja um múltiplo de três, você obtém algo semelhante à saída desejada:
$ 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
Você ainda precisa pesquisar 23 = X
, 07 = H
, 32 = g
etc. na tabela.