Je cherche un moyen de convertir une longue chaîne (à partir d'un vidage), qui représente des valeurs hexadécimales dans un tableau d'octets.
Je n'aurais pas pu mieux le formuler que la personne qui a posé la même question ici .
Mais pour le garder original, je vais le formuler à ma façon: supposons que j'ai une chaîne "00A0BF"
que je voudrais interpréter comme
byte[] {0x00,0xA0,0xBf}
que devrais-je faire?
Je suis un novice Java et j'ai fini par utiliser BigInteger
et faire attention aux zéros de tête. Mais je pense que c'est moche et je suis sûr que je manque quelque chose de simple.
BigInteger
ici .String.getBytes()
ne fonctionnera pas comme vous le pensez. J'ai dû l'apprendre à la dure.if ("FF".getBytes() != "ff".getBytes()) { System.out.println("Try again"); }
Réponses:
Voici une solution qui, je pense, est meilleure que n'importe quelle autre publiée jusqu'à présent:
Raisons pour lesquelles il s'agit d'une amélioration:
Sûr avec des zéros non significatifs (contrairement à BigInteger) et avec des valeurs d'octets négatives (contrairement à Byte.parseByte)
Ne convertit pas la chaîne en un
char[]
, ni ne crée des objets StringBuilder et String pour chaque octet unique.Aucune dépendance de bibliothèque qui peut ne pas être disponible
N'hésitez pas à ajouter une vérification d'argument via
assert
ou des exceptions si l'argument n'est pas connu pour être sûr.la source
One-liners:
Avertissements :
eckes
)Fabian
avoir noté), mais vous pouvez simplement prendre le code source si votre système manquejavax.xml
pour une raison quelconque. Merci à @ d'Bert Regelink
avoir extrait la source.la source
java.se
jeu de racines (par défaut) , il en résultera donc àClassNotFoundException
moins que vous ne le--add-modules java.se.ee
javax.xml.bind.DatatypeConverter
fournit déjà une méthode pour l'encodage / décodage des données Base64. VoirparseBase64Binary()
etprintBase64Binary()
.DataTypeConverter
, Java SE 11 a supprimé complètement l'API JAXB et n'est désormais inclus qu'avec Java EE. Vous pouvez également l'ajouter en tant que dépendance Maven, comme suggéré ici: stackoverflow.com/a/43574427/7347751La classe Hex du codec commun devrait faire cela pour vous.
http://commons.apache.org/codec/
la source
Vous pouvez maintenant utiliser BaseEncoding dans
guava
pour ce faire .Pour l'inverser, utilisez
la source
En fait, je pense que la solution BigInteger est très agréable:
Edit: Pas sûr pour les zéros non significatifs , comme l'a noté l'affiche.
la source
Pour ceux d'entre vous intéressés par le code réel derrière les One-liners de FractalizeR (j'en avais besoin puisque javax.xml.bind n'est pas disponible pour Android (par défaut)), cela vient de com.sun.xml.internal.bind. DatatypeConverterImpl.java :
la source
Le
HexBinaryAdapter
permet de rassembler et de démarsaler entreString
etbyte[]
.C'est juste un exemple que j'ai tapé ... Je l'utilise simplement tel quel et je n'ai pas besoin de créer une méthode distincte pour l'utiliser.
la source
Voici une méthode qui fonctionne réellement (basée sur plusieurs réponses semi-correctes précédentes):
Le seul problème possible que je peux voir est si la chaîne d'entrée est extrêmement longue; l'appel à toCharArray () crée une copie du tableau interne de la chaîne.
EDIT: Oh, et au fait, les octets sont signés en Java, donc votre chaîne d'entrée est convertie en [0, -96, -65] au lieu de [0, 160, 191]. Mais vous le saviez probablement déjà.
la source
Dans Android, si vous travaillez avec hexadécimal, vous pouvez essayer okio .
utilisation simple:
et le résultat sera
la source
La
BigInteger()
méthode de java.math est très lente et déconseillée.Integer.parseInt(HEXString, 16)
peut causer des problèmes avec certains caractères sans convertir en chiffre / entier
une bonne méthode de travail:
Une fonction:
Amusez-vous, bonne chance
la source
EDIT: comme indiqué par @mmyers, cette méthode ne fonctionne pas sur les entrées qui contiennent des sous-chaînes correspondant aux octets avec le bit le plus élevé ("80" - "FF"). L'explication se trouve au bogue ID: 6259307 Byte.parseByte ne fonctionnant pas comme annoncé dans la documentation du SDK .
la source
Pour ce que ça vaut, voici une autre version qui prend en charge les chaînes de longueur impaire, sans recourir à la concaténation de chaînes.
la source
J'ai toujours utilisé une méthode comme
cette méthode se divise sur des valeurs hexadécimales séparées par des espaces, mais il ne serait pas difficile de diviser la chaîne sur d'autres critères tels que des groupements de deux caractères.
la source
Byte
/byte
: bit le plus élevé défini sansJ'aime la solution Character.digit, mais voici comment je l'ai résolue
la source
Le Code présenté par Bert Regelink ne fonctionne tout simplement pas. Essayez ce qui suit:
la source
J'ai trouvé que Kernel Panic avait la solution la plus utile pour moi, mais j'ai rencontré des problèmes si la chaîne hexadécimale était un nombre impair. résolu de cette façon:
J'ajoute un certain nombre de nombres hexadécimaux à un tableau, donc je passe la référence au tableau que j'utilise, et l'int dont j'ai besoin converti et renvoyant la position relative du numéro hexadécimal suivant. Ainsi, le tableau d'octets final a [0] nombre de paires hexadécimales, [1 ...] paires hexadécimales, puis le nombre de paires ...
la source
Sur la base de la solution votée par les opérateurs, les éléments suivants devraient être un peu plus efficaces:
Parce que: la conversion initiale en tableau char épargne les vérifications de longueur dans charAt
la source
Si vous avez une préférence pour les flux Java 8 comme style de codage, cela peut être obtenu en utilisant uniquement des primitives JDK.
Les
, 0, s2.size()
paramètres de la fonction de concaténation du collecteur peuvent être omis si cela ne vous dérange pas d'attraperIOException
.la source
la source
Ma solution formelle:
Est similaire à la fonction PHP hex2bin () mais en style Java.
Exemple:
la source
En retard à la fête, mais j'ai fusionné la réponse ci-dessus de DaveL dans une classe avec l'action inverse - juste au cas où cela aiderait.
Et classe de test JUnit:
la source
Je sais que c'est un fil très ancien, mais j'aime quand même ajouter mon centime.
Si j'ai vraiment besoin de coder une simple chaîne hexadécimale en convertisseur binaire, je voudrais le faire comme suit.
la source
De loin pas la solution la plus propre. Mais cela fonctionne pour moi et est bien formaté:
Le résultat:
la source
Je pense qu'il le fera pour vous. Je l'ai bricolé à partir d'une fonction similaire qui a renvoyé les données sous forme de chaîne:
la source
Pour moi, c'était la solution, HEX = "FF01" puis divisé en FF (255) et 01 (01)
la source