¿Cómo convertir una matriz de bytes en una cadena hexadecimal en Java?
649
Tengo una matriz de bytes llena de números hexadecimales e imprimirla de manera fácil es bastante inútil porque hay muchos elementos no imprimibles. Lo que necesito es el código hexadecimal exacto en forma de:3a5f771c
¿Por qué no probarlo primero y mostrarnos lo que tienes? No tienes nada que perder y todo que ganar. Integer tiene un toHexString(...)método que puede ayudar si esto es lo que estás buscando. También String.format(...)puede hacer algunos trucos de formateo con la %2xcadena de código.
"Lo que necesito es el código hexadecimal exacto en forma de: 3a5f771c ..." - solicitó una forma exacta, pero no proporcionó un ejemplo exacto. Continuando con lo que proporcionó, convierta los primeros cuatro bytes en una cadena, luego concatene las elipses en la cadena.
jww
1
Con la ayuda de stream en Java 8, se puede implementar simplemente como: static String byteArrayToHex (byte [] a) {return IntStream.range (0, a.length) .mapToObj (i -> String.format ("% 02x ", a [i])) .reduce ((acc, v) -> acc +" "+ v) .get (); }
tibetty
Respuestas:
901
De la discusión aquí , y especialmente esta respuesta, esta es la función que uso actualmente:
Mis propios puntos de referencia pequeños (un millón de bytes mil veces, 256 bytes 10 millones de veces) demostraron que es mucho más rápido que cualquier otra alternativa, aproximadamente la mitad del tiempo en matrices largas. En comparación con la respuesta que obtuve, cambiar a operaciones bit a bit, como se sugirió en la discusión, redujo aproximadamente un 20% del tiempo para las matrices largas. (Editar: cuando digo que es más rápido que las alternativas, me refiero al código alternativo que se ofrece en las discusiones. El rendimiento es equivalente a Commons Codec, que usa un código muy similar).
Versión 2k20, con respecto a las cadenas compactas de Java 9:
Acabo de encontrar javax.xml.bind.DataTypeConverter , parte de la distribución estándar. ¿Por qué no surge esto cuando buscas este tipo de problema en Google? Muchas herramientas útiles, incluidas String printHexBinary(byte[])y byte[] parseHexBinary(String). printHexBinaryes, sin embargo, mucho (2x) más lento que la función en esta respuesta. (Verifiqué la fuente; usa a stringBuilder. parseHexBinaryUsa una matriz.) Realmente, sin embargo, para la mayoría de los propósitos es lo suficientemente rápido y probablemente ya lo tenga.
maybeWeCouldStealAVan
75
+1 para la respuesta ya que Android no tiene DataTypeConverter
Vaiden
77
@maybeWeCouldStealAVan: JDK 7 ahora es de código abierto. ¿Deberíamos enviar un parche para mejorar el rendimiento printHexBinary?
kevinarpe
3
@maybeWeCouldStealAVan ¿podría explicar cómo funciona esto? Lo sigo en su mayor parte, pero realmente me gusta entender lo que sucede cuando uso el código. ¡Gracias!
jjNford
24
javax.xml.bind.DataTypeConverterestá siendo eliminado de Java 11.
@cytinus: mi voto negativo ocurrió hace 4 meses, así que no estoy completamente seguro de lo que estaba pensando, pero probablemente estaba objetando el tamaño de la biblioteca. Esta es una pequeña función dentro del programa; no es necesario agregar una biblioteca tan voluminosa al proyecto para realizarla.
ArtOfWarfare
66
@ArtOfWarefare Estoy de acuerdo, así que en lugar de import org.apache.commons.codec.*;usted podría hacerloimport org.apache.commons.codec.binary.Hex;
cytinus
12
@ArtOfWarfare Tengo que estar en desacuerdo. Lo único terrible es que las bibliotecas de apache commons no se incluyen por defecto con JRE y JDK. Hay algunas bibliotecas que son tan útiles que realmente deberían estar en su ruta de clase por defecto, y esta es una de ellas.
corsiKa
29
Recomiendo encarecidamente que esta respuesta se cambie como la respuesta principal. Siempre vote para usar una biblioteca de código abierto, bien probada y de rendimiento sobre código personalizado que no mejore.
Dmitriy Likhten
66
O en caso de que use BouncyCastle ( org.bouncycastle: bcprov-jdk15on ), puede usar esta clase:, org.bouncycastle.util.encoders.Hexcon este método:String toHexString(byte[] data)
En Java 8 y versiones anteriores, JAXB era parte de la biblioteca estándar de Java. Se desaprobó con Java 9 y se eliminó con Java 11 , como parte de un esfuerzo por mover todos los paquetes Java EE a sus propias bibliotecas. Es una larga historia . Ahora, javax.xml.bindno existe, y si desea utilizar JAXB, que contiene DatatypeConverter, deberá instalar la API JAXB y JAXB Runtime de Maven.
Una buena solución, aunque lamentablemente no es válida en Android.
Kazriko
@Kazriko tal vez quieras leer code.google.com/p/dalvik/wiki/JavaxPackages . Es una forma de obtener clases de Java en Android. Pero si solo quieres convertir a hexadecimal, no vale la pena.
PhoneixS
13
DatatypeConverter ya no es accesible a partir de JDK 9
pmcollins
3
@PhoneixS Todavía está allí, pero no forma parte del tiempo de ejecución predeterminado (debido a los módulos Java 9).
Spotlight
2
no confíe en javax.xml.bind, se compila bien pero no se puede encontrar en tiempo de ejecución. si lo hace, prepárese para manejar java.lang.NoClassDefFoundError
Dmitry
227
La solución más simple, sin libs externas, sin constantes de dígitos:
Esto es muy lento, en promedio 1000 veces más lento (para 162 bytes de longitud) que el de la respuesta superior. Evite usar String.Format si el rendimiento es importante.
pt123
8
Quizás lento. Es bueno para cosas que suceden ocasionalmente, como inicio de sesión o similar.
Puntero nulo
29
Si es lento, ¿y qué? En mi caso de uso es solo para una declaración de depuración, así que gracias por este fragmento de código.
vikingsteve
8
Reutilizar una biblioteca al incluir archivos JAR adicionales de varias docenas de KB no sería exactamente eficiente si todo lo que necesita es esta función (en algunas plataformas como Android, todo el Jar se incluye en la aplicación final). Y a veces un código más corto y más claro es mejor cuando no se necesita rendimiento.
personne3000
2
@ personne3000 tal vez, pero en ese caso necesita soporte de transmisión, no una sola función de llamada. Este es fácil de entender y recordar, y por lo tanto de mantener.
En guayaba también puedes usar new HashCode(bytes).toString().
mfulton26
1
A partir de Guava 22.0 esHashCode.fromBytes(checksum).toString()
Devstr
43
Este simple oneliner funciona para mí String result = new BigInteger(1, inputBytes).toString(16);
EDITAR: usar esto eliminará los ceros iniciales, pero hey funcionó para mi caso de uso. Gracias @Voicu por señalarlo
@Voicu ... Y agregará un cero inicial el 50% del tiempo.
Maarten Bodewes
27
Aquí hay algunas opciones comunes ordenadas desde simples (una línea) hasta complejas (gran biblioteca). Si está interesado en el rendimiento, vea los micro puntos de referencia a continuación.
Opción 1: fragmento de código: simple
Una solución muy simple es usar la BigIntegerrepresentación hexadecimal de:
newBigInteger(1, someByteArray).toString(16)
Tenga en cuenta que dado que esto maneja números que no son cadenas de bytes arbitrarias , omitirá los ceros a la izquierda; esto puede o no ser lo que desea (por ejemplo, 000AE3vs 0AE3para una entrada de 3 bytes). Esto también es muy lento, aproximadamente 100 veces más lento en comparación con la siguiente opción.
Opción 2: fragmento de código - Avanzado
Aquí hay un fragmento de código completo, copiable y pegable que admite mayúsculas / minúsculas y endianness . Está optimizado para minimizar la complejidad de la memoria y maximizar el rendimiento y debería ser compatible con todas las versiones modernas de Java (5+).
privatestaticfinalchar[] LOOKUP_TABLE_LOWER =newchar[]{0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66};privatestaticfinalchar[] LOOKUP_TABLE_UPPER =newchar[]{0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};publicstaticString encode(byte[] byteArray,boolean upperCase,ByteOrder byteOrder){// our output size will be exactly 2x byte-array lengthfinalchar[] buffer =newchar[byteArray.length *2];// choose lower or uppercase lookup tablefinalchar[] lookup = upperCase ? LOOKUP_TABLE_UPPER : LOOKUP_TABLE_LOWER;int index;for(int i =0; i < byteArray.length; i++){// for little endian we count from last to first
index =(byteOrder ==ByteOrder.BIG_ENDIAN)? i : byteArray.length - i -1;// extract the upper 4 bit and look up char (0-A)
buffer[i <<1]= lookup[(byteArray[index]>>4)&0xF];// extract the lower 4 bit and look up char (0-A)
buffer[(i <<1)+1]= lookup[(byteArray[index]&0xF)];}returnnewString(buffer);}publicstaticString encode(byte[] byteArray){return encode(byteArray,false,ByteOrder.BIG_ENDIAN);}
El código fuente completo con licencia Apache v2 y decodificador se puede encontrar aquí .
Opción 3: Usar una pequeña biblioteca optimizada: bytes-java
Mientras trabajaba en mi proyecto anterior, creé este pequeño kit de herramientas para trabajar con bytes en Java. No tiene dependencias externas y es compatible con Java 7+. Incluye, entre otros, un decodificador / decodificador HEX muy rápido y bien probado:
Por supuesto, están los buenos códecs comunes . ( opinión de advertencia más adelante ) Mientras trabajaba en el proyecto descrito anteriormente, analicé el código y me decepcionó bastante; una gran cantidad de códigos no organizados duplicados, códecs obsoletos y exóticos probablemente solo sean útiles para muy pocas implementaciones muy complejas y lentas de códecs populares (específicamente Base64). Por lo tanto, tomaría una decisión informada si desea utilizarla o una alternativa. De todos modos, si todavía quieres usarlo, aquí hay un fragmento de código:
No es realmente la opción 8: compatibilidad con Java 9+ o 'No use JAXBs javax / xml / bind / DatatypeConverter'
En versiones anteriores de Java (8 y posteriores), el código Java para JAXB se incluía como dependencia de tiempo de ejecución. Desde Java 9 y la modularización de Jigsaw, su código no puede acceder a otro código fuera de su módulo sin una declaración explícita. Así que tenga en cuenta si obtiene una excepción como:
cuando se ejecuta en una JVM con Java 9+. Si es así, cambie las implementaciones a cualquiera de las alternativas anteriores. Ver también esta pregunta .
Micro Benchmarks
Estos son los resultados de una simple referencia de micro JMH que codifica conjuntos de bytes de diferentes tamaños . Los valores son operaciones por segundo, por lo que mayor es mejor.
Tenga en cuenta que los micro puntos de referencia a menudo no representan el comportamiento del mundo real, por lo tanto, tome estos resultados con un grano de sal.
|Name(ops/s)|16byte|32byte|128byte|0.95 MB ||----------------------|-----------:|-----------:|----------:|--------:||Opt1:BigInteger|2,088,514|1,008,357|133,665|4||Opt2/3:BytesLib|20,423,170|16,049,841|6,685,522|825||Opt4:ApacheCommons|17,503,857|12,382,018|4,319,898|529||Opt5:Guava|10,177,925|6,937,833|2,094,658|257||Opt6:Spring|18,704,986|13,643,374|4,904,805|601||Opt7: BC |7,501,666|3,674,422|1,077,236|152||Opt8: JAX-B |13,497,736|8,312,834|2,590,940|346|
Especificaciones: JDK 8u202, i7-7700K, Win10, 24GB Ram. Vea el punto de referencia completo aquí .
El más elegante, como él también señala, creo que es este:
staticfinalString HEXES ="0123456789ABCDEF";publicstaticString getHex(byte[] raw ){if( raw ==null){returnnull;}finalStringBuilder hex =newStringBuilder(2* raw.length );for(finalbyte b : raw ){
hex.append(HEXES.charAt((b &0xF0)>>4)).append(HEXES.charAt((b &0x0F)));}return hex.toString();}
Otros métodos se estaban ejecutando en mi muestra de 64 bytes en 5 ms, este se ejecuta en 0 ms. Probablemente sea mejor por falta de otras funciones de cadena como el formato.
Joseph Lust
if (raw == null) return nullNo es fallar rápido. ¿Por qué usarías alguna vez una nullllave?
Maarten Bodewes
Supongo que es un hábito ingresar validación. En este caso, evitamos cualquier excepción de referencia nula y dejamos que la persona que llama maneje los datos incorrectos.
Michael Bisbjerg
16
Con el menor costo de almacenar la tabla de búsqueda, esta implementación es simple y muy rápida.
¿Por qué no inicializar la BYTE2HEXmatriz con un forciclo simple ?
icza
@icza ¿Es eso posible con un campo estático final (también conocido como constante)?
nevelis
1
@nevelis Se puede asignar en un static { }bloque.
マ ル ち ゃ ん だ よ
1
@icza porque es más rápido codificar una tabla de búsqueda que generarla. Aquí la complejidad de la memoria se comercializa con la complejidad del tiempo, es decir. necesita más memoria pero más rápido (cada tanto en ambos extremos)
Patrick Favre
8
¿Qué tal esto?
String byteToHex(finalbyte[] hash){Formatter formatter =newFormatter();for(byte b : hash){
formatter.format("%02x", b);}String result = formatter.toString();
formatter.close();return result;}
Es una adaptación ligeramente más flexible de la respuesta aceptada. Personalmente, mantengo la respuesta aceptada y esta sobrecarga junto con ella, utilizable en más contextos.
Si su debuffer tiene un mal día, trate cluing en StringBuilder instanciación con un número de caracteres para el apoyo: StringBuilder buf = new StringBuilder(data.length * 2);.
barba gris
2
De acuerdo, hay muchas maneras de hacer esto, pero si decides usar una biblioteca, te sugiero que analices tu proyecto para ver si algo se ha implementado en una biblioteca que ya forma parte de tu proyecto antes de agregar una nueva biblioteca solo para hacer esto. Por ejemplo si aún no tienes
Agregar una jarra de utilidad para una función simple no es una buena opción. En su lugar, reúna sus propias clases de utilidad. lo siguiente es posible una implementación más rápida.
Una pequeña variante de la solución propuesta por @maybewecouldstealavan, que le permite agrupar visualmente N bytes en la cadena hexadecimal de salida:
No puedo encontrar ninguna solución en esta página que no
Usa un bucle
Use javax.xml.bind.DatatypeConverter que compila bien pero a menudo arroja java.lang.NoClassDefFoundError en tiempo de ejecución.
Aquí hay una solución que no tiene los defectos anteriores (sin promesas, la mía no tiene otros defectos)
import java.math.BigInteger;importstatic java.lang.System.out;publicfinalclassApp2{// | proposed solution.publicstaticString encode(byte[] bytes){finalint length = bytes.length;// | BigInteger constructor throws if it is given an empty array.if(length ==0){return"00";}finalint evenLength =(int)(2*Math.ceil(length /2.0));finalString format ="%0"+ evenLength +"x";finalString result =String.format (format,newBigInteger(bytes));return result;}publicstaticvoid main(String[] args)throwsException{// 00
out.println(encode(newbyte[]{}));// 01
out.println(encode(newbyte[]{1}));//203040
out.println(encode(newbyte[]{0x20,0x30,0x40}));// 416c6c20796f75722062617365206172652062656c6f6e6720746f2075732e
out.println(encode("All your base are belong to us.".getBytes()));}}
No pude obtener esto con 62 códigos de operación, pero si puedes vivir sin relleno 0 en caso de que el primer byte sea menor que 0x10, entonces la siguiente solución solo usa 23 códigos de operación. Realmente muestra cómo las soluciones "fáciles de implementar usted mismo" como "pad con un cero si la longitud de la cadena es impar" pueden ser bastante costosas si una implementación nativa no está disponible (o en este caso, si BigInteger tenía la opción de prefijar con ceros en Encadenar).
publicstaticString encode(byte[] bytes){finalint length = bytes.length;// | BigInteger constructor throws if it is given an empty array.if(length ==0){return"00";}returnnewBigInteger(bytes).toString(16);}
Mi solución se basa en la solución maybeWeCouldStealAVan, pero no se basa en ninguna tabla de búsqueda asignada adicionalmente. No utiliza ningún truco de conversión de 'int-to-char' (en realidad, lo Character.forDigit()hace, realizando alguna comparación para verificar cuál es realmente el dígito) y, por lo tanto, podría ser un poco más lento. Por favor, siéntase libre de usarlo donde quiera. Salud.
publicstaticString bytesToHex(finalbyte[] bytes){finalint numBytes = bytes.length;finalchar[] container =newchar[numBytes *2];for(int i =0; i < numBytes; i++){finalint b = bytes[i]&0xFF;
container[i *2]=Character.forDigit(b >>>4,0x10);
container[i *2+1]=Character.forDigit(b &0xF,0x10);}returnnewString(container);}
publicstaticbyte[] hexStringToByteArray(String s){int len = s.length();byte[] data =newbyte[len /2];for(int i =0; i < len; i +=2){
data[i /2]=(byte)((Character.digit(s.charAt(i),16)<<4)+Character.digit(s.charAt(i+1),16));}return data;}
privatestaticString bytesToHexString(byte[] bytes,int length){if(bytes ==null|| length ==0)returnnull;StringBuilder ret =newStringBuilder(2*length);for(int i =0; i < length ; i++){int b;
b =0x0f&(bytes[i]>>4);
ret.append("0123456789abcdef".charAt(b));
b =0x0f& bytes[i];
ret.append("0123456789abcdef".charAt(b));}return ret.toString();}
toHexString(...)
método que puede ayudar si esto es lo que estás buscando. TambiénString.format(...)
puede hacer algunos trucos de formateo con la%2x
cadena de código.Respuestas:
De la discusión aquí , y especialmente esta respuesta, esta es la función que uso actualmente:
Mis propios puntos de referencia pequeños (un millón de bytes mil veces, 256 bytes 10 millones de veces) demostraron que es mucho más rápido que cualquier otra alternativa, aproximadamente la mitad del tiempo en matrices largas. En comparación con la respuesta que obtuve, cambiar a operaciones bit a bit, como se sugirió en la discusión, redujo aproximadamente un 20% del tiempo para las matrices largas. (Editar: cuando digo que es más rápido que las alternativas, me refiero al código alternativo que se ofrece en las discusiones. El rendimiento es equivalente a Commons Codec, que usa un código muy similar).
Versión 2k20, con respecto a las cadenas compactas de Java 9:
fuente
String printHexBinary(byte[])
ybyte[] parseHexBinary(String)
.printHexBinary
es, sin embargo, mucho (2x) más lento que la función en esta respuesta. (Verifiqué la fuente; usa astringBuilder
.parseHexBinary
Usa una matriz.) Realmente, sin embargo, para la mayoría de los propósitos es lo suficientemente rápido y probablemente ya lo tenga.printHexBinary
?javax.xml.bind.DataTypeConverter
está siendo eliminado de Java 11.La biblioteca de códecs de Apache Commons tiene una clase Hex para hacer este tipo de trabajo.
fuente
import org.apache.commons.codec.*;
usted podría hacerloimport org.apache.commons.codec.binary.Hex;
org.bouncycastle.util.encoders.Hex
con este método:String toHexString(byte[] data)
El método
javax.xml.bind.DatatypeConverter.printHexBinary()
, parte de la Arquitectura Java para Enlace XML (JAXB) , era una forma conveniente de convertir unabyte[]
cadena hexadecimal. LaDatatypeConverter
clase también incluyó muchos otros métodos útiles de manipulación de datos.En Java 8 y versiones anteriores, JAXB era parte de la biblioteca estándar de Java. Se desaprobó con Java 9 y se eliminó con Java 11 , como parte de un esfuerzo por mover todos los paquetes Java EE a sus propias bibliotecas. Es una larga historia . Ahora,
javax.xml.bind
no existe, y si desea utilizar JAXB, que contieneDatatypeConverter
, deberá instalar la API JAXB y JAXB Runtime de Maven.Ejemplo de uso:
Resultará en:
Esta respuesta es la misma que esta .
fuente
La solución más simple, sin libs externas, sin constantes de dígitos:
fuente
Una solución de guayaba, para completar:
Ahora
hex
es"48656c6c6f20776f726c64"
.fuente
new HashCode(bytes).toString()
.HashCode.fromBytes(checksum).toString()
Este simple oneliner funciona para mí
String result = new BigInteger(1, inputBytes).toString(16);
EDITAR: usar esto eliminará los ceros iniciales, pero hey funcionó para mi caso de uso. Gracias @Voicu por señalarlo
fuente
Aquí hay algunas opciones comunes ordenadas desde simples (una línea) hasta complejas (gran biblioteca). Si está interesado en el rendimiento, vea los micro puntos de referencia a continuación.
Opción 1: fragmento de código: simple
Una solución muy simple es usar la
BigInteger
representación hexadecimal de:Tenga en cuenta que dado que esto maneja números que no son cadenas de bytes arbitrarias , omitirá los ceros a la izquierda; esto puede o no ser lo que desea (por ejemplo,
000AE3
vs0AE3
para una entrada de 3 bytes). Esto también es muy lento, aproximadamente 100 veces más lento en comparación con la siguiente opción.Opción 2: fragmento de código - Avanzado
Aquí hay un fragmento de código completo, copiable y pegable que admite mayúsculas / minúsculas y endianness . Está optimizado para minimizar la complejidad de la memoria y maximizar el rendimiento y debería ser compatible con todas las versiones modernas de Java (5+).
El código fuente completo con licencia Apache v2 y decodificador se puede encontrar aquí .
Opción 3: Usar una pequeña biblioteca optimizada: bytes-java
Mientras trabajaba en mi proyecto anterior, creé este pequeño kit de herramientas para trabajar con bytes en Java. No tiene dependencias externas y es compatible con Java 7+. Incluye, entre otros, un decodificador / decodificador HEX muy rápido y bien probado:
Puedes verlo en Github: bytes-java .
Opción 4: Códec de Apache Commons
Por supuesto, están los buenos códecs comunes . ( opinión de advertencia más adelante ) Mientras trabajaba en el proyecto descrito anteriormente, analicé el código y me decepcionó bastante; una gran cantidad de códigos no organizados duplicados, códecs obsoletos y exóticos probablemente solo sean útiles para muy pocas implementaciones muy complejas y lentas de códecs populares (específicamente Base64). Por lo tanto, tomaría una decisión informada si desea utilizarla o una alternativa. De todos modos, si todavía quieres usarlo, aquí hay un fragmento de código:
Opción 5: Google Guava
La mayoría de las veces ya tienes a la guayaba como dependencia. Si es así, solo use:
Opción 6: seguridad de primavera
Si usa Spring Framework con Spring Security , puede usar lo siguiente:
Opción 7: Castillo hinchable
Si ya usa el marco de seguridad Bouncy Castle , puede usar su utilidad
Hex
:No es realmente la opción 8: compatibilidad con Java 9+ o 'No use JAXBs javax / xml / bind / DatatypeConverter'
En versiones anteriores de Java (8 y posteriores), el código Java para JAXB se incluía como dependencia de tiempo de ejecución. Desde Java 9 y la modularización de Jigsaw, su código no puede acceder a otro código fuera de su módulo sin una declaración explícita. Así que tenga en cuenta si obtiene una excepción como:
cuando se ejecuta en una JVM con Java 9+. Si es así, cambie las implementaciones a cualquiera de las alternativas anteriores. Ver también esta pregunta .
Micro Benchmarks
Estos son los resultados de una simple referencia de micro JMH que codifica conjuntos de bytes de diferentes tamaños . Los valores son operaciones por segundo, por lo que mayor es mejor. Tenga en cuenta que los micro puntos de referencia a menudo no representan el comportamiento del mundo real, por lo tanto, tome estos resultados con un grano de sal.
Especificaciones: JDK 8u202, i7-7700K, Win10, 24GB Ram. Vea el punto de referencia completo aquí .
fuente
Utilice la clase DataTypeConverter
javax.xml.bind.DataTypeConverter
String hexString = DatatypeConverter.printHexBinary(bytes[] raw);
fuente
Usaría algo como esto para una longitud fija, como hashes:
fuente
Encontré tres formas diferentes aquí: http://www.rgagnon.com/javadetails/java-0596.html
El más elegante, como él también señala, creo que es este:
fuente
if (raw == null) return null
No es fallar rápido. ¿Por qué usarías alguna vez unanull
llave?Con el menor costo de almacenar la tabla de búsqueda, esta implementación es simple y muy rápida.
fuente
BYTE2HEX
matriz con unfor
ciclo simple ?static { }
bloque.¿Qué tal esto?
fuente
No necesitamos usar ninguna biblioteca externa o escribir código basado en bucles y constantes.
Es suficiente solo esto:
fuente
Prefiero usar esto:
Es una adaptación ligeramente más flexible de la respuesta aceptada. Personalmente, mantengo la respuesta aceptada y esta sobrecarga junto con ella, utilizable en más contextos.
fuente
Usualmente uso el siguiente método para la declaración de debuf, pero no sé si es la mejor manera de hacerlo o no
fuente
StringBuilder buf = new StringBuilder(data.length * 2);
.De acuerdo, hay muchas maneras de hacer esto, pero si decides usar una biblioteca, te sugiero que analices tu proyecto para ver si algo se ha implementado en una biblioteca que ya forma parte de tu proyecto antes de agregar una nueva biblioteca solo para hacer esto. Por ejemplo si aún no tienes
tal vez tienes ...
fuente
Si está utilizando el marco de Spring Security, puede usar:
fuente
Agregar una jarra de utilidad para una función simple no es una buena opción. En su lugar, reúna sus propias clases de utilidad. lo siguiente es posible una implementación más rápida.
fuente
Una pequeña variante de la solución propuesta por @maybewecouldstealavan, que le permite agrupar visualmente N bytes en la cadena hexadecimal de salida:
Es decir:
fuente
No puedo encontrar ninguna solución en esta página que no
Aquí hay una solución que no tiene los defectos anteriores (sin promesas, la mía no tiene otros defectos)
No pude obtener esto con 62 códigos de operación, pero si puedes vivir sin relleno 0 en caso de que el primer byte sea menor que 0x10, entonces la siguiente solución solo usa 23 códigos de operación. Realmente muestra cómo las soluciones "fáciles de implementar usted mismo" como "pad con un cero si la longitud de la cadena es impar" pueden ser bastante costosas si una implementación nativa no está disponible (o en este caso, si BigInteger tenía la opción de prefijar con ceros en Encadenar).
fuente
Mi solución se basa en la solución maybeWeCouldStealAVan, pero no se basa en ninguna tabla de búsqueda asignada adicionalmente. No utiliza ningún truco de conversión de 'int-to-char' (en realidad, lo
Character.forDigit()
hace, realizando alguna comparación para verificar cuál es realmente el dígito) y, por lo tanto, podría ser un poco más lento. Por favor, siéntase libre de usarlo donde quiera. Salud.fuente
// Cambiar los bytes es más eficiente // Puedes usar este también
fuente
Si está buscando una matriz de bytes exactamente como esta para python, he convertido esta implementación de Java en python.
fuente
fuente
Aquí hay una
java.util.Base64
implementación similar (parcial), ¿no es bonita?fuente
fuente
fuente