Por dois dias eu apanhei para conseguir escrever uma string hexadecimal em um socket. A string se parecia com isso:
String string = "08A235A410";
Repare que esta string representa um hexadecimal, sendo que cada par de caracteres representa um byte hexadecimal. Por exemplo, os dois primeiros caracteres da string formam o hexadecimal 0×08, os próximos 0xA2 e assim por diante.
Para que eu pudesse escrever isso no socket eu precisava converter a string para um array de byte e cada byte seria um hexadecimal. Como fazer essa conversão?
public byte[] hexString2ByteArray(String str) {
int len = str.length();
byte[] bytes = new byte[len / 2];
for(int i = 0; i < len; i += 2) {
bytes[i / 2] = (byte) ((Character.digit(str.charAt(i), 16) << 4) + Character.digit(str.charAt(i+1), 16));
}
return bytes;
}
Este método é bem simples. Ele lê de dois em dois caracteres, converte cada caractere de base 16 para decimal, faz um deslocamento de 4 bits para a esquerda do primeiro caractere, depois soma o resultado do primeiro e do segundo caractere e por fim faz um cast para byte.
Desse modo eu consegui converter uma string em um array de bytes e foi só escrever no socket.
Nota! Um hexadecimal usa 8 bits para representar seu valor, que em decimal seria de 0 a 255. Um byte também precisa de 8 bits para representar seu valor, mas em Java um byte é representado de -128 a 127. A diferença entre eles é que um é signed e o outro é unsigned. Ou seja, um usa sinal (positivo/negativo) e o outro não. Tipos que são signed usam o primeiro dos 8 bits para representar o sinal, já os unsigned usam todos os bits para representar o seu valor. O que torna possível fazer a conversão é que tanto o byte quanto o hexadecimal usam 8 bits e por isso tem um mesmo range. De -128 a 127 ou de 0 a 255 da no mesmo, ambos tem a mesma capacidade.
Fontes:
