Cuando trabajaba en el algoritmo para crear un MAC ANSI X9.19 tuve que convertir el resultado que estaba en un array de bytes (byte[] result) en un String que representase cada byte como un valor Hexadecimal. Para ello, utilicé una función que encontré en stackoverflow y que resultaba elegante a simple vista:
private static String toHex(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (byte b : bytes) { sb.append(String.format("%02x", b & 0xff)); // "%02X" for uppercase } return sb.toString(); }
El caso es que mientras buscaba el código para el MAC ANSI X9.19 me encontré muchas formas de implementar esta conversión y he tenido la curiosidad de indagar cuál es la más eficiente.
Quiero comentar que hay librerías de uso bastante común que incorporan esta conversión, por ejemplo:
- org.apache.commons.codec.binary.Hex.encodeHexString() de la librería Apache Commons Codec
- org.bouncycastle.util.encoders.Hex.encode() de la librería Bouncy Castle
Pero es más, aunque mucha gente no lo sabe y acaba recurriendo a librerías externas, viene también incluida en la propia distribución de Java: javax.xml.bind.DatatypeConverter.printHexBinary()
Pues bien, ninguna de las implementaciones comentadas resulta ser demasiado eficiente. Así que si necesitáis una conversión que sea rápida, no queréis incluir librerías externas o estáis programando en Android y necesitáis esta conversión porque se dispone del DatatypeConverter en Android, aquí va el método óptimo de conversión. Mediante un benchmark personalizado que construí he podido comprobar que es el doble de rápido que el mejor de los demás que he probado y 100 veces más rápido que las conversiones incluidas en librerías comentadas o la propia DatatypeConverter.printHexBinary()
private static final char[] hexArray = "0123456789ABCDEF".toCharArray(); /** * Encode the input bytes producing a Hexadecimal output string * * @param bytes * @return Hexadecimal representation of the input bytes */ public static final String byteArrayToHexString(final byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { int v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); }
Todo el mérito y mi reconocimiento es para esta contribución en stackoverflow: http://stackoverflow.com/a/9855338
No hay comentarios:
Publicar un comentario