[RESOLVIDO] Converter array de bytes MD5 para String hexadecimal

Olá :slight_smile:

Então, pessoal. Ontem eu tive a necessidade de fazer uma conversão de um array de bytes MD5 para uma String hexadecimal. Com um código apresentado pelo entanglement aqui, e algumas adaptações tudo funcionou como deveria.

Mas qual o problema? Eu não faço ideia de como esse código funciona. O problema aqui não é o que deve ser feito, mas como foi feito. Alguém consegue me explicar como esse código funciona? Eu realmente não gosto de usar um código que não entendo hehehe.

Alguns links para um material que me ajuda já serão suficientes, só quero saber como pesquisar. Fazendo pesquisas no google eu só encontro métodos com código pronto, e não é isso que eu quero.

Só pra constar aqui no tópico. O método do entanglement é esse: private static char[] hexDigits = "0123456789ABCDEF".toCharArray(); public static String hex (byte[] digest) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < digest.length; i++) { sb.append(hexDigits[(digest[i] >> 4) & 0xF]); sb.append(hexDigits[digest[i] & 0xF]); } return sb.toString(); }

Acho que esse link está mais claro:

[quote=ViniGodoy]Acho que esse link está mais claro:


Ah, entendi como funciona o processo agora. Acho que minha dúvida agora é mais conceitual do que outra coisa.

  • Por que é necessário deslocar o último bit 4x para a direita e depois concatenar com o resultado do & no byte original?
  • A utilização do 0xF é pelo fato do maior valor possível ser 15, correto?

Imagine que você tem 1 byte. Ele é formado por 2 caracteres hexa. Vamos supor o número 0x5A

0x5A = 0101 1010

Você quer separar individualmente os dois caracteres que compõe esse número hexadecimal. Uma das formas é fazer um &, colocando um nos bits relevantes. Nesse caso, você gostaria de separar os últimos 4 bits, ou seja, fazer um & com:

[code]0101 1010 //0x5A
0000 1111 & //0x0F

0000 1010 //0x0A
[/code]

Como você pode ver, agora o caracter A está separado do número 5. Mas você também quer imprimir o 5, certo?
Como separa-lo? A resposta é: vamos "empurrar" os bits da frente quatro bits para direita. Assim, ao fazermos o &, faremos com os bits da frente:

[code]0101 1010 //0x5A
0000 0101 //Afastando 4 bits para a direita: 0x5A >> 4 = 0x05
0000 1111 & //0x0F

0000 0101 //0x05
[/code]

Bom, agora você tem o número 0xA (10 decimal) e o número 0x5 (5 decimal).
Basta usar a função Integer.toString para imprimir esses valores em hexa.

Agora eu entendi.

E só pra finalizar, é realmente necessário utilizar o shift não é mesmo?

Eu cheguei a pensar que então poderíamos simplesmente aplicar o & por 0xFF[code]
0101 1010 //0x5A
1111 1111 & //0xFF

0101 1010 //0x5A [/code]Mas 0x5A não é a mesma coisa que 0x05 separado de 0x0A.

Eu teria que aplicar a máscara e aí dividir os valores depois, não é?

Como eu disse, a dúvida era conceitual. Valeu Vini!

Ah, e sim, poderia chamar Integer.toString direto, afinal, 0x5A é um número válido, e de valor 0x5A.

Mas da forma postada, você garante que:
a) O bit de sinal será desprezado
b) O 0 a esquerda será impresso.

Por isso ele imprimiu cada conjunto de 4 bytes individualmente.