Apanhando para os bits

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:

http://stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java

Posted in Java | Tagged , , , , , | Leave a comment