El método más optimizado que he encontrado en Java es el siguiente:
byte[] javax.xml.bind.DatatypeConverter.parseHexBinary(String lexicalXSDHexBinary)Para mostrar su eficiencia voy a compararlo con este otro método [stackoverflow.com] bastante bien valorado por los usuarios:
private static byte[] hexStringToByteArray(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
}
return data;
}
Y para ello, aprovecho para mostrar como se puede hacer un pequeño benchmark comparativo:
import javax.xml.bind.DatatypeConverter;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
/**
* @author Raul
*/
public final class Benchmark {
private static byte[] hexStringToByteArray(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
}
return data;
}
private static final char[] VALORES = "0123456789ABCDEF".toCharArray();
private static final int MIN = 0;
private static final int MAX = 15;
private static final int NUM_TESTS = 1000000;
private static final int LENGTH_HEX = 64;
private static final long TIME_ACCURACY = 1000000;
public static void main(String[] args) {
// Preparamos los tests
Random random = new Random();
int range = MAX - MIN + 1;
List<String> tests = new LinkedList<String>();
for (int i = 0; i < NUM_TESTS; i++) {
StringBuilder sb = new StringBuilder(LENGTH_HEX);
for (int b = 0; b < LENGTH_HEX; b++) {
int randomPos = random.nextInt(range) + MIN;
sb.append(VALORES[randomPos]);
}
tests.add(sb.toString());
}
// Iniciamos
long startTime = 0, endTime = 0;
System.gc();
// DatatypeConverter
startTime = System.nanoTime();
for (String test : tests) {
byte[] result = DatatypeConverter.parseHexBinary(test);
}
endTime = System.nanoTime();
System.out.printf("%22s %10d%n", "DatatypeConverter:",
(endTime - startTime) / TIME_ACCURACY);
System.gc();
// hexStringToByteArray
startTime = System.nanoTime();
for (String test : tests) {
byte[] result = hexStringToByteArray(test);
}
endTime = System.nanoTime();
System.out.printf("%22s %10d%n", "hexStringToByteArray:",
(endTime - startTime) / TIME_ACCURACY);
System.gc();
}
}
Resultado:
DatatypeConverter: 663 hexStringToByteArray: 908
El paquete de DatatypeConverter no está disponible en Android, así que los que necesitéis este método podéis utilizar el hexStringToByteArray expuesto aquí, o el código del parseHexBinary extraído del propio paquete y que podéis encontrar en http://stackoverflow.com/a/11139098