Hex para base64 em * nix [duplicado]

1

Note: I have marked this question as a duplicate of another question. But I am keeping it nonetheless as it has an example and a clearly explained answer, so hopefully it should help others.

Eu preciso converter uma seqüência de caracteres hexadecimais em base64 como feito por este conversor on-line em * nix.

Para " 5C78336D77D8DF448007D277DAD5C569 " (Hex) eu sei que a saída esperada é " XHgzbXfY30SAB9J32tXFaQ== " (base64).

Mas quando eu tento convertê-lo em binário e, em seguida, base64 eu recebo isso:

[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==

Alguém pode me apontar na direção certa?

    
por Kent Pawar 25.07.2013 / 17:53

2 respostas

6

Se você quiser usar xxd para decodificar sua sequência hexadecimal, será necessário usar xxd -r -p . E assim, você começa:

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

-r é para reversão, para que xxd decodifique seu dump hexadecimal e -p é para dizer que a entrada é um dump simples (ou seja, uma sequência hexadecimal sem adornos), sem formatação como linha Número (s).

    
por 25.07.2013 / 18:21
2

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.

    
por 31.07.2013 / 02:51