Comment convertir un tableau d'octets en une chaîne hexadécimale en Java?
649
J'ai un tableau d'octets rempli de nombres hexadécimaux et l'imprimer facilement est assez inutile car il existe de nombreux éléments non imprimables. J'ai besoin du code hexadécimal exact sous la forme de:3a5f771c
Pourquoi ne pas simplement l'essayer d'abord et nous montrer ce que vous avez. Vous n'avez rien à perdre et tout à gagner. Integer a une toHexString(...)méthode qui peut vous aider si c'est ce que vous recherchez. String.format(...)Peut également faire quelques astuces de mise en forme soignées en utilisant la %2xchaîne de code.
"Ce dont j'ai besoin, c'est le code hexadécimal exact sous la forme: 3a5f771c ..." - vous avez demandé un formulaire exact, mais vous n'avez pas fourni d'exemple exact. En suivant ce que vous avez fourni, convertissez les quatre premiers octets en chaîne, puis concaténez les ellipses en chaîne.
2014 à 9h18
1
Avec l'aide de stream dans Java 8, il peut être simplement implémenté comme: String statique byteArrayToHex (byte [] a) {return IntStream.range (0, a.length) .mapToObj (i -> String.format ("% 02x ", a [i])) .reduce ((acc, v) -> acc +" "+ v) .get (); }
tibetty
Réponses:
901
D'après la discussion ici , et surtout cette réponse, voici la fonction que j'utilise actuellement:
Mes propres tests de performance minuscules (un million d'octets mille fois, 256 octets 10 millions de fois) ont montré qu'il était beaucoup plus rapide que toute autre alternative, environ la moitié du temps sur de longues matrices. Par rapport à la réponse dont je l'ai tirée, passer à des opérations au niveau du bit --- comme suggéré dans la discussion --- réduire d'environ 20% le temps pour les longues matrices. (Edit: Quand je dis que c'est plus rapide que les alternatives, je veux dire le code alternatif proposé dans les discussions. Les performances sont équivalentes à Commons Codec, qui utilise un code très similaire.)
Version 2k20, par rapport aux chaînes compactes Java 9:
Je viens de trouver javax.xml.bind.DataTypeConverter , une partie de la distribution standard. Pourquoi cela ne se produit-il pas lorsque vous recherchez ce type de problème sur Google? Beaucoup d'outils utiles, y compris String printHexBinary(byte[])et byte[] parseHexBinary(String). printHexBinaryest, cependant, beaucoup (2x) plus lent que la fonction dans cette réponse. (J'ai vérifié la source; il utilise un stringBuilder. parseHexBinaryUtilise un tableau.) Vraiment, cependant, pour la plupart des cas, c'est assez rapide et vous l'avez probablement déjà.
peut
75
+1 pour la réponse car Android n'a pas DataTypeConverter
Vaiden
7
@maybeWeCouldStealAVan: JDK 7 est maintenant open source. Nous devrions soumettre un patch pour améliorer les performances de printHexBinary?
kevinarpe
3
@maybeWeCouldStealAVan pourriez-vous s'il vous plaît expliquer comment cela fonctionne. Je suis pour la plupart, mais j'aime vraiment comprendre ce qui se passe lors de l'utilisation du code. Merci!
jjNford
24
javax.xml.bind.DataTypeConverterest en cours de suppression de Java 11.
The Impaler
421
La bibliothèque Apache Commons Codec possède une classe Hex pour effectuer exactement ce type de travail.
import org.apache.commons.codec.binary.Hex;String foo ="I am a string";byte[] bytes = foo.getBytes();System.out.println(Hex.encodeHexString( bytes ));
@cytinus - Mon vote négatif s'est produit il y a 4 mois, donc je ne suis pas tout à fait certain de ce que je pensais, mais je m'opposais probablement à la taille de la bibliothèque. Il s'agit d'une petite fonction au sein du programme; il n'est pas nécessaire d'ajouter une bibliothèque aussi volumineuse au projet pour l'exécuter.
ArtOfWarfare
6
@ArtOfWarefare Je suis d'accord, donc au lieu de import org.apache.commons.codec.*;vous pourriez le faireimport org.apache.commons.codec.binary.Hex;
cytinus
12
@ArtOfWarfare Je dois être en désaccord. La seule chose terrible est que les bibliothèques Apache Commons ne sont pas incluses par défaut avec le JRE et le JDK. Il y a certaines bibliothèques qui sont si utiles qu'elles devraient vraiment être sur votre chemin de classe par défaut, et c'est l'une d'entre elles.
corsiKa
29
Je recommande fortement que cette réponse soit permutée comme première réponse. Votez toujours pour utiliser une bibliothèque open source bien testée et performante sur du code personnalisé qui ne l'améliore pas.
Dmitriy Likhten
6
Ou si vous utilisez BouncyCastle ( org.bouncycastle: bcprov-jdk15on ), vous pouvez utiliser cette classe :,org.bouncycastle.util.encoders.Hex avec cette méthode:String toHexString(byte[] data)
Dans Java 8 et versions antérieures, JAXB faisait partie de la bibliothèque standard Java. Il a été déconseillé avec Java 9 et supprimé avec Java 11 , dans le cadre d'un effort pour déplacer tous les packages Java EE dans leurs propres bibliothèques. C'est une longue histoire . Maintenant, javax.xml.bindn'existe pas, et si vous souhaitez utiliser JAXB, qui contient DatatypeConverter, vous devrez installer l' API JAXB et JAXB Runtime de Maven.
Une bonne solution, mais malheureusement pas celle qui est valable dans Android.
Kazriko
@Kazriko, vous voulez peut-être lire code.google.com/p/dalvik/wiki/JavaxPackages . C'est un moyen d'obtenir des classes javax dans Android. Mais si vous voulez seulement convertir en hexadécimal, cela ne vaut pas la peine.
PhoneixS
13
DatatypeConverter n'est plus accessible à partir du JDK 9
pmcollins
3
@PhoneixS Il est toujours là, mais ne fait pas partie du runtime par défaut (en raison des modules Java 9).
Spotlight
2
ne vous fiez pas à javax.xml.bind, il compile bien mais ne peut pas être trouvé au moment de l'exécution. si vous le faites, soyez prêt à gérer java.lang.NoClassDefFoundError
Dmitry
227
Solution la plus simple, pas de bibliothèques externes, pas de constantes de chiffres:
C'est très lent, en moyenne 1000 fois plus lent (pour 162 octets de long) que celui de la réponse supérieure. Évitez d'utiliser String.Format si les performances sont importantes.
pt123
8
Peut-être lent. C'est bon pour les choses qui se produisent occasionnellement, comme la connexion ou similaire.
Pointer Null
29
Si c'est lent, alors quoi? Dans mon cas d'utilisation, c'est juste pour une instruction de débogage, donc merci pour ce fragment de code.
vikingsteve
8
Réutiliser une bibliothèque en incluant des fichiers JAR supplémentaires de plusieurs dizaines de ko ne serait pas exactement efficace si tout ce dont vous avez besoin est cette fonction (sur certaines plateformes comme Android, tout le Jar est inclus dans l'application finale). Et parfois, un code plus court et plus clair est meilleur lorsque les performances ne sont pas nécessaires.
personne3000
2
@ personne3000 peut-être, mais dans ce cas, vous avez besoin d'une prise en charge de flux, pas d'une seule fonction d'appel. celui-ci est facile à comprendre et à retenir, et donc à entretenir.
En goyave, vous pouvez également utiliser new HashCode(bytes).toString().
mfulton26
1
En date de Guava 22.0 c'estHashCode.fromBytes(checksum).toString()
Devstr
43
Ce simple oneliner fonctionne pour moi String result = new BigInteger(1, inputBytes).toString(16);
EDIT - L'utilisation de ceci supprimera les zéros non significatifs, mais bon pour mon cas d'utilisation. Merci @Voicu de l'avoir signalé
@Voicu ... Et cela ajoutera un zéro de tête 50% du temps.
Maarten Bodewes
27
Voici quelques options courantes classées du simple (une ligne) au complexe (immense bibliothèque). Si vous êtes intéressé par les performances, consultez les micro-benchmarks ci-dessous.
Option 1: extrait de code - simple
Une solution très simple consiste à utiliser la BigIntegerreprésentation hexadécimale de:
newBigInteger(1, someByteArray).toString(16)
Notez que puisque cela gère les nombres et non les chaînes d'octets arbitraires, il omettra les zéros en tête - cela peut ou non être ce que vous voulez (par exemple 000AE3vs 0AE3pour une entrée de 3 octets). C'est également très lent, environ 100 fois plus lent que l'option suivante.
Option 2: extrait de code - avancé
Voici un extrait de code complet, copiable et collable prenant en charge les majuscules / minuscules et l' endianisme . Il est optimisé pour minimiser la complexité de la mémoire et maximiser les performances et doit être compatible avec toutes les versions Java modernes (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);}
Le code source complet avec licence et décodeur Apache v2 peut être trouvé ici .
Option 3: Utilisation d'une petite bibliothèque optimisée: bytes-java
En travaillant sur mon projet précédent, j'ai créé cette petite boîte à outils pour travailler avec des octets en Java. Il n'a pas de dépendances externes et est compatible avec Java 7+. Il comprend, entre autres, un décodeur / décodeur HEX très rapide et bien testé:
Bien sûr, il y a les bons codecs communs . ( avis d'avertissement à venir ) En travaillant sur le projet décrit ci-dessus, j'ai analysé le code et j'ai été très déçu; un grand nombre de codes non organisés en double, de codecs obsolètes et exotiques, probablement utiles uniquement pour très peu et des mises en œuvre trop complexes et lentes de codecs populaires (spécifiquement Base64). Je prendrais donc une décision éclairée si vous souhaitez l'utiliser ou une alternative. Quoi qu'il en soit, si vous souhaitez toujours l'utiliser, voici un extrait de code:
Pas vraiment l'option 8: Compatibilité Java 9+ ou 'Ne pas utiliser JAXBs javax / xml / bind / DatatypeConverter'
Dans les versions précédentes de Java (8 et inférieures), le code Java pour JAXB était inclus en tant que dépendance d'exécution. Depuis la modularisation Java 9 et Jigsaw, votre code ne peut pas accéder à un autre code en dehors de son module sans déclaration explicite. Soyez donc conscient si vous obtenez une exception comme:
lors de l'exécution sur une machine virtuelle Java avec Java 9+. Si c'est le cas, basculez les implémentations vers l'une des alternatives ci-dessus. Voir aussi cette question .
Micro repères
Voici les résultats d'un simple micro-benchmark JMH encodant des tableaux d'octets de différentes tailles . Les valeurs sont des opérations par seconde, donc plus c'est mieux.
Notez que les micro-repères ne représentent souvent pas un comportement réel, alors prenez ces résultats avec un grain de sel.
|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|
Spécifications: JDK 8u202, i7-7700K, Win10, 24 Go de RAM. Voir le benchmark complet ici .
Le plus élégant, comme il le note également, je pense que c'est celui-ci:
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();}
D'autres méthodes fonctionnaient sur mon échantillon de 64 octets en 5 ms, celle-ci s'exécute en 0 ms. Probablement mieux faute de toute autre fonction String comme le format.
Joseph Lust
if (raw == null) return nulln'est pas un échec rapide. Pourquoi voudriez-vous jamais utiliser une nullclé?
Maarten Bodewes
Je suppose que c'est une habitude de saisir valider. Dans ce cas, nous empêchons toute exception de référence Null et laissons à l'appelant le soin de gérer les données incorrectes.
Michael Bisbjerg
16
Au moindre coût de stockage de la table de recherche, cette implémentation est simple et très rapide.
Pourquoi ne pas initialiser le BYTE2HEXtableau avec un forcycle simple ?
icza
@icza Est-ce même possible avec un champ final statique (aka constant)?
nevelis
1
@nevelis Il peut être affecté dans un static { }bloc.
マ ル ち ゃ ん だ よ
1
@icza car il est plus rapide de coder en dur une table de recherche que de la générer. Ici, la complexité de la mémoire est échangée avec la complexité du temps, c'est-à-dire a besoin de plus de mémoire mais plus rapidement (de façon si légère aux deux extrémités)
Patrick Favre
8
Que dis-tu de ça?
String byteToHex(finalbyte[] hash){Formatter formatter =newFormatter();for(byte b : hash){
formatter.format("%02x", b);}String result = formatter.toString();
formatter.close();return result;}
C'est une adaptation un peu plus souple de la réponse acceptée. Personnellement, je garde la réponse acceptée et cette surcharge avec elle, utilisable dans plus de contextes.
Si votre debuffer a une mauvaise journée, essayez cluing dans StringBuilder instanciation avec un certain nombre de caractères à l' appui: StringBuilder buf = new StringBuilder(data.length * 2);.
greybeard
2
Ok, donc il y a un tas de façons de le faire, mais si vous décidez d'utiliser une bibliothèque, je vous suggère de fouiller dans votre projet pour voir si quelque chose a été implémenté dans une bibliothèque qui fait déjà partie de votre projet avant d'ajouter une nouvelle bibliothèque juste pour faire ça. Par exemple, si vous n'avez pas déjà
Ajouter un pot utilitaire pour une fonction simple n'est pas une bonne option. Assemblez plutôt vos propres classes d'utilitaires. ce qui suit est une mise en œuvre plus rapide possible.
Une petite variante de la solution proposée par @maybewecouldstealavan, qui vous permet de regrouper visuellement N octets ensemble dans la chaîne hexadécimale de sortie:
Je ne trouve aucune solution sur cette page qui ne
Utilisez une boucle
Utilisez javax.xml.bind.DatatypeConverter qui compile correctement mais jette souvent java.lang.NoClassDefFoundError au moment de l'exécution.
Voici une solution qui n'a pas les défauts ci-dessus (aucune promesse que la mienne n'a pas d'autres défauts cependant)
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()));}}
Je ne pouvais pas obtenir cela sous 62 opcodes, mais si vous pouvez vivre sans remplissage 0 au cas où le premier octet est inférieur à 0x10, la solution suivante n'utilise que 23 opcodes. Montre vraiment comment des solutions «faciles à implémenter vous-même» comme «pad avec un zéro si la longueur de chaîne est impaire» peuvent devenir assez coûteuses si une implémentation native n'est pas déjà disponible (ou dans ce cas, si BigInteger avait la possibilité de préfixer avec des zéros dans toString).
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);}
Ma solution est basée sur la solution peut-être de WeCouldStealAVan, mais ne repose sur aucune table de recherche allouée en plus. Il n'utilise pas de piratage `` int-to-char '' (en fait, le Character.forDigit()fait, en effectuant une comparaison pour vérifier ce qu'est vraiment le chiffre) et peut donc être un peu plus lent. N'hésitez pas à l'utiliser où vous le souhaitez. À votre santé.
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éthode qui peut vous aider si c'est ce que vous recherchez.String.format(...)
Peut également faire quelques astuces de mise en forme soignées en utilisant la%2x
chaîne de code.Réponses:
D'après la discussion ici , et surtout cette réponse, voici la fonction que j'utilise actuellement:
Mes propres tests de performance minuscules (un million d'octets mille fois, 256 octets 10 millions de fois) ont montré qu'il était beaucoup plus rapide que toute autre alternative, environ la moitié du temps sur de longues matrices. Par rapport à la réponse dont je l'ai tirée, passer à des opérations au niveau du bit --- comme suggéré dans la discussion --- réduire d'environ 20% le temps pour les longues matrices. (Edit: Quand je dis que c'est plus rapide que les alternatives, je veux dire le code alternatif proposé dans les discussions. Les performances sont équivalentes à Commons Codec, qui utilise un code très similaire.)
Version 2k20, par rapport aux chaînes compactes Java 9:
la source
String printHexBinary(byte[])
etbyte[] parseHexBinary(String)
.printHexBinary
est, cependant, beaucoup (2x) plus lent que la fonction dans cette réponse. (J'ai vérifié la source; il utilise unstringBuilder
.parseHexBinary
Utilise un tableau.) Vraiment, cependant, pour la plupart des cas, c'est assez rapide et vous l'avez probablement déjà.printHexBinary
?javax.xml.bind.DataTypeConverter
est en cours de suppression de Java 11.La bibliothèque Apache Commons Codec possède une classe Hex pour effectuer exactement ce type de travail.
la source
import org.apache.commons.codec.*;
vous pourriez le faireimport org.apache.commons.codec.binary.Hex;
org.bouncycastle.util.encoders.Hex
avec cette méthode:String toHexString(byte[] data)
La méthode
javax.xml.bind.DatatypeConverter.printHexBinary()
, qui fait partie de l' architecture Java pour la liaison XML (JAXB) , était un moyen pratique de convertir abyte[]
en chaîne hexadécimale. LaDatatypeConverter
classe comprenait également de nombreuses autres méthodes de manipulation de données utiles.Dans Java 8 et versions antérieures, JAXB faisait partie de la bibliothèque standard Java. Il a été déconseillé avec Java 9 et supprimé avec Java 11 , dans le cadre d'un effort pour déplacer tous les packages Java EE dans leurs propres bibliothèques. C'est une longue histoire . Maintenant,
javax.xml.bind
n'existe pas, et si vous souhaitez utiliser JAXB, qui contientDatatypeConverter
, vous devrez installer l' API JAXB et JAXB Runtime de Maven.Exemple d'utilisation:
Aura pour résultat:
Cette réponse est la même que celle-ci .
la source
Solution la plus simple, pas de bibliothèques externes, pas de constantes de chiffres:
la source
Une solution Guava, pour être complet:
Maintenant
hex
est"48656c6c6f20776f726c64"
.la source
new HashCode(bytes).toString()
.HashCode.fromBytes(checksum).toString()
Ce simple oneliner fonctionne pour moi
String result = new BigInteger(1, inputBytes).toString(16);
EDIT - L'utilisation de ceci supprimera les zéros non significatifs, mais bon pour mon cas d'utilisation. Merci @Voicu de l'avoir signalé
la source
Voici quelques options courantes classées du simple (une ligne) au complexe (immense bibliothèque). Si vous êtes intéressé par les performances, consultez les micro-benchmarks ci-dessous.
Option 1: extrait de code - simple
Une solution très simple consiste à utiliser la
BigInteger
représentation hexadécimale de:Notez que puisque cela gère les nombres et non les chaînes d'octets arbitraires, il omettra les zéros en tête - cela peut ou non être ce que vous voulez (par exemple
000AE3
vs0AE3
pour une entrée de 3 octets). C'est également très lent, environ 100 fois plus lent que l'option suivante.Option 2: extrait de code - avancé
Voici un extrait de code complet, copiable et collable prenant en charge les majuscules / minuscules et l' endianisme . Il est optimisé pour minimiser la complexité de la mémoire et maximiser les performances et doit être compatible avec toutes les versions Java modernes (5+).
Le code source complet avec licence et décodeur Apache v2 peut être trouvé ici .
Option 3: Utilisation d'une petite bibliothèque optimisée: bytes-java
En travaillant sur mon projet précédent, j'ai créé cette petite boîte à outils pour travailler avec des octets en Java. Il n'a pas de dépendances externes et est compatible avec Java 7+. Il comprend, entre autres, un décodeur / décodeur HEX très rapide et bien testé:
Vous pouvez le vérifier sur Github: bytes-java .
Option 4: Codec Apache Commons
Bien sûr, il y a les bons codecs communs . ( avis d'avertissement à venir ) En travaillant sur le projet décrit ci-dessus, j'ai analysé le code et j'ai été très déçu; un grand nombre de codes non organisés en double, de codecs obsolètes et exotiques, probablement utiles uniquement pour très peu et des mises en œuvre trop complexes et lentes de codecs populaires (spécifiquement Base64). Je prendrais donc une décision éclairée si vous souhaitez l'utiliser ou une alternative. Quoi qu'il en soit, si vous souhaitez toujours l'utiliser, voici un extrait de code:
Option 5: Google Guava
Le plus souvent, vous avez déjà la goyave comme dépendance. Si oui, utilisez simplement:
Option 6: sécurité du printemps
Si vous utilisez le framework Spring avec Spring Security, vous pouvez utiliser les éléments suivants:
Option 7: Château gonflable
Si vous utilisez déjà le cadre de sécurité Bouncy Castle, vous pouvez utiliser son
Hex
util:Pas vraiment l'option 8: Compatibilité Java 9+ ou 'Ne pas utiliser JAXBs javax / xml / bind / DatatypeConverter'
Dans les versions précédentes de Java (8 et inférieures), le code Java pour JAXB était inclus en tant que dépendance d'exécution. Depuis la modularisation Java 9 et Jigsaw, votre code ne peut pas accéder à un autre code en dehors de son module sans déclaration explicite. Soyez donc conscient si vous obtenez une exception comme:
lors de l'exécution sur une machine virtuelle Java avec Java 9+. Si c'est le cas, basculez les implémentations vers l'une des alternatives ci-dessus. Voir aussi cette question .
Micro repères
Voici les résultats d'un simple micro-benchmark JMH encodant des tableaux d'octets de différentes tailles . Les valeurs sont des opérations par seconde, donc plus c'est mieux. Notez que les micro-repères ne représentent souvent pas un comportement réel, alors prenez ces résultats avec un grain de sel.
Spécifications: JDK 8u202, i7-7700K, Win10, 24 Go de RAM. Voir le benchmark complet ici .
la source
Utiliser la classe DataTypeConverter
javax.xml.bind.DataTypeConverter
String hexString = DatatypeConverter.printHexBinary(bytes[] raw);
la source
J'utiliserais quelque chose comme ça pour une longueur fixe, comme des hachages:
la source
J'ai trouvé trois façons différentes ici: http://www.rgagnon.com/javadetails/java-0596.html
Le plus élégant, comme il le note également, je pense que c'est celui-ci:
la source
if (raw == null) return null
n'est pas un échec rapide. Pourquoi voudriez-vous jamais utiliser unenull
clé?Au moindre coût de stockage de la table de recherche, cette implémentation est simple et très rapide.
la source
BYTE2HEX
tableau avec unfor
cycle simple ?static { }
bloc.Que dis-tu de ça?
la source
Nous n'avons pas besoin d'utiliser de bibliothèque externe ou d'écrire du code basé sur des boucles et des constantes.
Est-ce suffisant:
la source
Je préfère utiliser ceci:
C'est une adaptation un peu plus souple de la réponse acceptée. Personnellement, je garde la réponse acceptée et cette surcharge avec elle, utilisable dans plus de contextes.
la source
J'utilise généralement la méthode suivante pour l'instruction debuf, mais je ne sais pas si c'est la meilleure façon de le faire ou non
la source
StringBuilder buf = new StringBuilder(data.length * 2);
.Ok, donc il y a un tas de façons de le faire, mais si vous décidez d'utiliser une bibliothèque, je vous suggère de fouiller dans votre projet pour voir si quelque chose a été implémenté dans une bibliothèque qui fait déjà partie de votre projet avant d'ajouter une nouvelle bibliothèque juste pour faire ça. Par exemple, si vous n'avez pas déjà
vous avez peut-être ...
la source
Si vous utilisez le framework Spring Security, vous pouvez utiliser:
la source
Ajouter un pot utilitaire pour une fonction simple n'est pas une bonne option. Assemblez plutôt vos propres classes d'utilitaires. ce qui suit est une mise en œuvre plus rapide possible.
la source
Une petite variante de la solution proposée par @maybewecouldstealavan, qui vous permet de regrouper visuellement N octets ensemble dans la chaîne hexadécimale de sortie:
C'est:
la source
Je ne trouve aucune solution sur cette page qui ne
Voici une solution qui n'a pas les défauts ci-dessus (aucune promesse que la mienne n'a pas d'autres défauts cependant)
Je ne pouvais pas obtenir cela sous 62 opcodes, mais si vous pouvez vivre sans remplissage 0 au cas où le premier octet est inférieur à 0x10, la solution suivante n'utilise que 23 opcodes. Montre vraiment comment des solutions «faciles à implémenter vous-même» comme «pad avec un zéro si la longueur de chaîne est impaire» peuvent devenir assez coûteuses si une implémentation native n'est pas déjà disponible (ou dans ce cas, si BigInteger avait la possibilité de préfixer avec des zéros dans toString).
la source
Ma solution est basée sur la solution peut-être de WeCouldStealAVan, mais ne repose sur aucune table de recherche allouée en plus. Il n'utilise pas de piratage `` int-to-char '' (en fait, le
Character.forDigit()
fait, en effectuant une comparaison pour vérifier ce qu'est vraiment le chiffre) et peut donc être un peu plus lent. N'hésitez pas à l'utiliser où vous le souhaitez. À votre santé.la source
// Le décalage des octets est plus efficace // Vous pouvez aussi utiliser celui-ci
la source
Si vous recherchez un tableau d'octets exactement comme celui-ci pour python, j'ai converti cette implémentation Java en python.
la source
la source
Voici une
java.util.Base64
implémentation de type (partielle), n'est-ce pas joli?la source
la source
la source