J'ai un tableau d'octets. Je veux que chaque chaîne d'octets de ce tableau soit convertie en ses valeurs hexadécimales correspondantes.
Existe-t-il une fonction en Java pour convertir un tableau d'octets en hexadécimal?
J'ai un tableau d'octets. Je veux que chaque chaîne d'octets de ce tableau soit convertie en ses valeurs hexadécimales correspondantes.
Existe-t-il une fonction en Java pour convertir un tableau d'octets en hexadécimal?
Réponses:
byte[] bytes = {-1, 0, 1, 2, 3 };
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
System.out.println(sb.toString());
// prints "FF 00 01 02 03 "
java.util.Formatter
syntaxe
%[flags][width]conversion
'0'
- Le résultat sera complété par zéro2
'X'
- Le résultat est formaté sous la forme d'un entier hexadécimal, majusculeEn regardant le texte de la question, il est également possible que ce soit ce qui est demandé:
String[] arr = {"-1", "0", "10", "20" };
for (int i = 0; i < arr.length; i++) {
arr[i] = String.format("%02x", Byte.parseByte(arr[i]));
}
System.out.println(java.util.Arrays.toString(arr));
// prints "[ff, 00, 0a, 14]"
Plusieurs réponses ici utilise Integer.toHexString(int)
; c'est faisable, mais avec quelques mises en garde. Puisque le paramètre est un int
, une conversion primitive d'élargissement est effectuée en byte
argument, ce qui implique une extension de signe.
byte b = -1;
System.out.println(Integer.toHexString(b));
// prints "ffffffff"
Le 8 bits byte
, qui est signé en Java, est étendu à un signe 32 bits int
. Pour annuler efficacement cette extension de signe, on peut masquer le byte
avec 0xFF
.
byte b = -1;
System.out.println(Integer.toHexString(b & 0xFF));
// prints "ff"
Un autre problème avec l'utilisation toHexString
est qu'il ne remplit pas de zéros:
byte b = 10;
System.out.println(Integer.toHexString(b & 0xFF));
// prints "a"
Les deux facteurs combinés devraient rendre la String.format
solution plus préférable.
byte
, du -128
au 127
, inclustoHexString
. Vous devez le masquer avec & 0xFF
, c'est Integer.toHexString(-46 & 0xFF)
-à- dire "d2"
.
byte
valeur avec à & 0xFF
chaque fois. la format
solution ci-dessus peut également nécessiter un masquage en fonction de ce que vous utilisez réellement comme argument.
Je poste parce qu'aucune des réponses existantes n'explique pourquoi leurs approches fonctionnent, ce qui, à mon avis, est vraiment important pour ce problème. Dans certains cas, cela fait apparaître la solution proposée inutilement compliquée et subtile. Pour illustrer, je vais fournir une approche assez simple, mais je vais fournir un peu plus de détails pour aider à illustrer pourquoi cela fonctionne.
Tout d'abord, qu'essayons-nous de faire? Nous voulons convertir une valeur d'octet (ou un tableau d'octets) en une chaîne qui représente une valeur hexadécimale en ASCII. La première étape consiste donc à découvrir exactement ce qu'est un octet en Java:
Le type de données octet est un entier de complément à deux signé de 8 bits . Il a une valeur minimale de -128 et une valeur maximale de 127 (inclus). Le type de données octet peut être utile pour économiser de la mémoire dans de grands tableaux, où les économies de mémoire sont réellement importantes. Ils peuvent également être utilisés à la place de int où leurs limites aident à clarifier votre code; le fait que la plage d'une variable soit limitée peut servir de forme de documentation.
Qu'est-ce que ça veut dire? Quelques petites choses: d'abord et surtout, cela signifie que nous travaillons avec 8 bits . Ainsi, par exemple, nous pouvons écrire le nombre 2 comme 0000 0010. Cependant, comme il s'agit du complément à deux, nous écrivons un 2 négatif comme ceci: 1111 1110. Cela signifie également que la conversion en hexadécimal est très simple. Autrement dit, vous convertissez simplement chaque segment de 4 bits directement en hexadécimal. Notez que pour donner un sens aux nombres négatifs dans ce schéma, vous devez d'abord comprendre le complément à deux. Si vous ne comprenez pas déjà le complément à deux, vous pouvez lire une excellente explication, ici: http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html
Une fois qu'un nombre est en complément à deux, il est très simple de le convertir en hexadécimal. En général, la conversion de binaire en hexadécimal est très simple, et comme vous le verrez dans les deux exemples suivants, vous pouvez passer directement du complément à deux à l'hex.
Exemple 1: Convertissez 2 en hexadécimal.
1) Commencez par convertir 2 en binaire en complément à deux:
2 (base 10) = 0000 0010 (base 2)
2) Maintenant, convertissez le binaire en hexadécimal:
0000 = 0x0 in hex
0010 = 0x2 in hex
therefore 2 = 0000 0010 = 0x02.
Exemple 2: Convertissez -2 (en complément à deux) en Hex.
1) Commencez par convertir -2 en binaire en complément à deux:
-2 (base 10) = 0000 0010 (direct conversion to binary)
1111 1101 (invert bits)
1111 1110 (add 1)
therefore: -2 = 1111 1110 (in two's complement)
2) Convertissez maintenant en hexadécimal:
1111 = 0xF in hex
1110 = 0xE in hex
therefore: -2 = 1111 1110 = 0xFE.
Maintenant que nous avons couvert le concept, vous constaterez que nous pouvons réaliser ce que nous voulons avec un simple masquage et décalage. La chose clé à comprendre est que l'octet que vous essayez de convertir est déjà en complément à deux. Vous ne faites pas cette conversion vous-même. Je pense que c'est un point de confusion majeur sur cette question. Prenez par exemple le tableau d'octets suivant:
byte[] bytes = new byte[]{-2,2};
Nous les avons simplement convertis manuellement en hexadécimal, ci-dessus, mais comment pouvons-nous le faire en Java? Voici comment:
Étape 1: Créez un StringBuffer pour contenir notre calcul.
StringBuffer buffer = new StringBuffer();
Étape 2: Isolez les bits d'ordre supérieur, convertissez-les en hexadécimal et ajoutez-les au tampon
Étant donné le nombre binaire 1111 1110, nous pouvons isoler les bits d'ordre supérieur en les décalant d'abord de 4, puis en mettant à zéro le reste du nombre. Logiquement, c'est simple, cependant, les détails d'implémentation en Java (et dans de nombreux langages) introduisent une ride à cause de l'extension de signe. Essentiellement, lorsque vous déplacez une valeur d'octet, Java convertit d'abord votre valeur en un entier, puis effectue l'extension de signe. Ainsi, alors que vous vous attendez à ce que 1111 1110 >> 4 soit 0000 1111, en réalité, en Java, il est représenté comme le complément à deux 0xFFFFFFFF!
Revenons donc à notre exemple:
1111 1110 >> 4 (shift right 4) = 1111 1111 1111 1111 1111 1111 1111 1111 (32 bit sign-extended number in two's complement)
On peut alors isoler les bits avec un masque:
1111 1111 1111 1111 1111 1111 1111 1111 & 0xF = 0000 0000 0000 0000 0000 0000 0000 1111
therefore: 1111 = 0xF in hex.
En Java, nous pouvons faire tout cela d'un seul coup:
Character.forDigit((bytes[0] >> 4) & 0xF, 16);
La fonction forDigit mappe simplement le nombre que vous lui passez sur l'ensemble des nombres hexadécimaux 0-F.
Étape 3: Ensuite, nous devons isoler les bits d'ordre inférieur. Puisque les bits que nous voulons sont déjà dans la bonne position, nous pouvons simplement les masquer:
1111 1110 & 0xF = 0000 0000 0000 0000 0000 0000 0000 1110 (recall sign extension from before)
therefore: 1110 = 0xE in hex.
Comme auparavant, en Java, nous pouvons faire tout cela en un seul coup:
Character.forDigit((bytes[0] & 0xF), 16);
En mettant tout cela ensemble, nous pouvons le faire comme une boucle for et convertir le tableau entier:
for(int i=0; i < bytes.length; i++){
buffer.append(Character.forDigit((bytes[i] >> 4) & 0xF, 16));
buffer.append(Character.forDigit((bytes[i] & 0xF), 16));
}
Espérons que cette explication rend les choses plus claires pour ceux d'entre vous qui se demandent exactement ce qui se passe dans les nombreux exemples que vous trouverez sur Internet. J'espère que je n'ai pas fait d'erreurs flagrantes, mais les suggestions et corrections sont les bienvenues!
Character.digit()
, comme(byte) ((Character.digit(str.charAt(0), 16) << 4) + Character.digit(str.charAt(1), 16))
Le moyen le plus rapide que j'ai trouvé pour le faire est le suivant:
private static final String HEXES = "0123456789ABCDEF";
static String getHex(byte[] raw) {
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
C'est environ 50 fois plus rapide que String.format
. si vous souhaitez le tester:
public class MyTest{
private static final String HEXES = "0123456789ABCDEF";
@Test
public void test_get_hex() {
byte[] raw = {
(byte) 0xd0, (byte) 0x0b, (byte) 0x01, (byte) 0x2a, (byte) 0x63,
(byte) 0x78, (byte) 0x01, (byte) 0x2e, (byte) 0xe3, (byte) 0x6c,
(byte) 0xd2, (byte) 0xb0, (byte) 0x78, (byte) 0x51, (byte) 0x73,
(byte) 0x34, (byte) 0xaf, (byte) 0xbb, (byte) 0xa0, (byte) 0x9f,
(byte) 0xc3, (byte) 0xa9, (byte) 0x00, (byte) 0x1e, (byte) 0xd5,
(byte) 0x4b, (byte) 0x89, (byte) 0xa3, (byte) 0x45, (byte) 0x35,
(byte) 0xd6, (byte) 0x10,
};
int N = 77777;
long t;
{
t = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
}
hex.toString();
}
System.out.println(System.currentTimeMillis() - t); // 50
}
{
t = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
StringBuilder hex = new StringBuilder(2 * raw.length);
for (byte b : raw) {
hex.append(String.format("%02X", b));
}
hex.toString();
}
System.out.println(System.currentTimeMillis() - t); // 2535
}
}
}
Edit : Je viens de trouver quelque chose juste un peu plus vite et qui tient sur une ligne mais n'est pas compatible avec JRE 9. Utilisez à vos risques et périls
import javax.xml.bind.DatatypeConverter;
DatatypeConverter.printHexBinary(raw);
printHexBinary
du code source de src.zip de jdk, ce qui semble 1 fois plus rapide que la 1ère méthode.
Essayez de cette façon:
byte bv = 10;
String hexString = Integer.toHexString(bv);
Traiter avec tableau (si je vous ai bien compris):
byte[] bytes = {9, 10, 11, 15, 16};
StringBuffer result = new StringBuffer();
for (byte b : bytes) {
result.append(String.format("%02X ", b));
result.append(" "); // delimiter
}
return result.toString();
Comme mentionné sur les lubrifiants polygéniques, String.format()
est la bonne réponse par rapport à Integer.toHexString()
(car elle traite correctement les nombres négatifs).
-1
.
bv
il renvoie un seul caractère hexadécimal . Alors que le reste du code renvoie une chaîne de caractères hexadécimaux . J'ai changé le code avec le délimiteur pour que vous puissiez le comprendre maintenant.
Integer.toHexString
si vous masquez l' extension de signe byte
avec 0xFF
pour annuler.
Un moyen court et simple de convertir byte[]
en chaîne hexadécimale en utilisant BigInteger
:
import java.math.BigInteger;
byte[] bytes = new byte[] {(byte)255, 10, 20, 30};
String hex = new BigInteger(1, bytes).toString(16);
System.out.println(hex); // ff0a141e
La classe de java.math.BigInteger
classe système intégrée ( java.math.BigInteger ) est compatible avec les données binaires et hexadécimales:
BigInteger(signum=1, byte[])
pour créer un grand entier par byte[]
(définir son premier paramètre signum
= 1
pour gérer correctement les octets négatifs)BigInteger.toString(16)
pour convertir le grand entier en chaîne hexadécimalenew BigInteger("ffa74b", 16)
- ne gère pas correctement le zéro non significatifSi vous souhaitez avoir le zéro non significatif dans le résultat hexadécimal, vérifiez sa taille et ajoutez le zéro manquant si nécessaire:
if (hex.length() % 2 == 1)
hex = "0" + hex;
Utilisez new BigInteger(1, bytes)
, au lieu de new BigInteger(bytes)
, parce que Java est " cassé par conception " et que le byte
type de données ne contient pas d'octets mais de petits entiers signés [-128 ... 127]. Si le premier octet est négatif, le BigInteger
suppose que vous transmettez un grand entier négatif. Passez simplement 1
comme premier paramètre ( signum=1
).
La conversion de hex enbyte[]
est délicate: parfois un zéro non significatif entre dans la sortie produite et il doit être nettoyé comme ceci:
byte[] bytes = new BigInteger("ffa74b", 16).toByteArray();
if (bytes[0] == 0) {
byte[] newBytes = new byte[bytes.length - 1];
System.arraycopy(bytes, 1, newBytes, 0, newBytes.length);
bytes = newBytes;
}
La dernière note est le si le byte[]
a plusieurs zéros non significatifs, ils seront perdus.
La meilleure solution est ce badass one-liner:
String hex=DatatypeConverter.printHexBinary(byte[] b);
comme mentionné ici
new BigInteger(byteArray).toString(16)
est la voie à suivre alors. Y a-t-il des problèmes de perf avec ça?
Si vous voulez une représentation hexadécimale de largeur constante, c'est-à-dire 0A
au lieu de A
, afin de pouvoir récupérer les octets sans ambiguïté, essayez format()
:
StringBuilder result = new StringBuilder();
for (byte bb : byteArray) {
result.append(String.format("%02X", bb));
}
return result.toString();
Si vous êtes heureux d'utiliser une bibliothèque externe, la org.apache.commons.codec.binary.Hex
classe a une encodeHex
méthode qui prend a byte[]
et retourne a char[]
. Cette méthode est BEAUCOUP plus rapide que l'option de format et encapsule les détails de la conversion. Vient également avec une decodeHex
méthode pour la conversion opposée.
javax
espace de noms n'est pas toujours disponible.
Vous pouvez utiliser la méthode de la bibliothèque Bouncy Castle Provider :
org.bouncycastle.util.encoders.Hex.toHexString(byteArray);
Le package Bouncy Castle Crypto est une implémentation Java d'algorithmes cryptographiques. Ce fichier contient le fournisseur JCE et une API légère pour les API de cryptographie Bouncy Castle pour JDK 1.5 à JDK 1.8.
Dépendance Maven:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
ou depuis Apache Commons Codec :
org.apache.commons.codec.binary.Hex.encodeHexString(byteArray);
Le package Apache Commons Codec contient un encodeur et des décodeurs simples pour différents formats tels que Base64 et Hexadecimal. En plus de ces encodeurs et décodeurs largement utilisés, le progiciel de codec maintient également une collection d'utilitaires de codage phonétique.
Dépendance Maven:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
C'est le code que j'ai trouvé pour fonctionner le plus rapidement jusqu'à présent. Je l'ai exécuté sur des tableaux de 109015 octets de longueur 32, en 23ms. Je l'exécutais sur une VM, donc il fonctionnera probablement plus vite sur du métal nu.
public static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
public static char[] encodeHex( final byte[] data ){
final int l = data.length;
final char[] out = new char[l<<1];
for( int i=0,j=0; i<l; i++ ){
out[j++] = HEX_DIGITS[(0xF0 & data[i]) >>> 4];
out[j++] = HEX_DIGITS[0x0F & data[i]];
}
return out;
}
Alors tu peux juste faire
String s = new String( encodeHex(myByteArray) );
BigInteger n = new BigInteger(byteArray);
String hexa = n.toString(16));
BigInteger(byteArrayOf(-1, 2, 3, 4, 5)).toString(16)
retourne"-fdfcfbfb"
(int) 255
) puisque les octets Java sont signés, le résultat devrait donc être FF02030405
. Si vous essayez la solution @Jerinaw ci-dessus, vous verrez qu'elle imprimera la sortie correcte. Voir également la solution de Svetlin Nakov ci-dessous.
Voici une fonction simple pour convertir l'octet en hexadécimal
private static String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < data.length; i++) {
int halfbyte = (data[i] >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9))
buf.append((char) ('0' + halfbyte));
else
buf.append((char) ('a' + (halfbyte - 10)));
halfbyte = data[i] & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}
D'autres ont couvert le cas général. Mais si vous avez un tableau d'octets d'une forme connue, par exemple une adresse MAC, vous pouvez:
byte[] mac = { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 };
String str = String.format("%02X:%02X:%02X:%02X:%02X:%02X",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
La création (et la destruction) d'un groupe d' String
instances n'est pas un bon moyen si les performances sont un problème.
Veuillez ignorer ces arguments détaillés (dupliqués) vérifiant les déclarations if
. C'est pour (un autre) but éducatif.
Projet maven complet: http://jinahya.googlecode.com/svn/trunk/com.googlecode.jinahya/hex-codec/
Codage...
/**
* Encodes a single nibble.
*
* @param decoded the nibble to encode.
*
* @return the encoded half octet.
*/
protected static int encodeHalf(final int decoded) {
switch (decoded) {
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
return decoded + 0x30; // 0x30('0') - 0x39('9')
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
return decoded + 0x57; // 0x41('a') - 0x46('f')
default:
throw new IllegalArgumentException("illegal half: " + decoded);
}
}
/**
* Encodes a single octet into two nibbles.
*
* @param decoded the octet to encode.
* @param encoded the array to which each encoded nibbles are written.
* @param offset the offset in the array.
*/
protected static void encodeSingle(final int decoded, final byte[] encoded,
final int offset) {
if (encoded == null) {
throw new IllegalArgumentException("null encoded");
}
if (encoded.length < 2) {
// not required
throw new IllegalArgumentException(
"encoded.length(" + encoded.length + ") < 2");
}
if (offset < 0) {
throw new IllegalArgumentException("offset(" + offset + ") < 0");
}
if (offset >= encoded.length - 1) {
throw new IllegalArgumentException(
"offset(" + offset + ") >= encoded.length(" + encoded.length
+ ") - 1");
}
encoded[offset] = (byte) encodeHalf((decoded >> 4) & 0x0F);
encoded[offset + 1] = (byte) encodeHalf(decoded & 0x0F);
}
/**
* Decodes given sequence of octets into a sequence of nibbles.
*
* @param decoded the octets to encode
*
* @return the encoded nibbles.
*/
protected static byte[] encodeMultiple(final byte[] decoded) {
if (decoded == null) {
throw new IllegalArgumentException("null decoded");
}
final byte[] encoded = new byte[decoded.length << 1];
int offset = 0;
for (int i = 0; i < decoded.length; i++) {
encodeSingle(decoded[i], encoded, offset);
offset += 2;
}
return encoded;
}
/**
* Encodes given sequence of octets into a sequence of nibbles.
*
* @param decoded the octets to encode.
*
* @return the encoded nibbles.
*/
public byte[] encode(final byte[] decoded) {
return encodeMultiple(decoded);
}
Décodage...
/**
* Decodes a single nibble.
*
* @param encoded the nibble to decode.
*
* @return the decoded half octet.
*/
protected static int decodeHalf(final int encoded) {
switch (encoded) {
case 0x30: // '0'
case 0x31: // '1'
case 0x32: // '2'
case 0x33: // '3'
case 0x34: // '4'
case 0x35: // '5'
case 0x36: // '6'
case 0x37: // '7'
case 0x38: // '8'
case 0x39: // '9'
return encoded - 0x30;
case 0x41: // 'A'
case 0x42: // 'B'
case 0x43: // 'C'
case 0x44: // 'D'
case 0x45: // 'E'
case 0x46: // 'F'
return encoded - 0x37;
case 0x61: // 'a'
case 0x62: // 'b'
case 0x63: // 'c'
case 0x64: // 'd'
case 0x65: // 'e'
case 0x66: // 'f'
return encoded - 0x57;
default:
throw new IllegalArgumentException("illegal half: " + encoded);
}
}
/**
* Decodes two nibbles into a single octet.
*
* @param encoded the nibble array.
* @param offset the offset in the array.
*
* @return decoded octet.
*/
protected static int decodeSingle(final byte[] encoded, final int offset) {
if (encoded == null) {
throw new IllegalArgumentException("null encoded");
}
if (encoded.length < 2) {
// not required
throw new IllegalArgumentException(
"encoded.length(" + encoded.length + ") < 2");
}
if (offset < 0) {
throw new IllegalArgumentException("offset(" + offset + ") < 0");
}
if (offset >= encoded.length - 1) {
throw new IllegalArgumentException(
"offset(" + offset + ") >= encoded.length(" + encoded.length
+ ") - 1");
}
return (decodeHalf(encoded[offset]) << 4)
| decodeHalf(encoded[offset + 1]);
}
/**
* Encodes given sequence of nibbles into a sequence of octets.
*
* @param encoded the nibbles to decode.
*
* @return the encoded octets.
*/
protected static byte[] decodeMultiple(final byte[] encoded) {
if (encoded == null) {
throw new IllegalArgumentException("null encoded");
}
if ((encoded.length & 0x01) == 0x01) {
throw new IllegalArgumentException(
"encoded.length(" + encoded.length + ") is not even");
}
final byte[] decoded = new byte[encoded.length >> 1];
int offset = 0;
for (int i = 0; i < decoded.length; i++) {
decoded[i] = (byte) decodeSingle(encoded, offset);
offset += 2;
}
return decoded;
}
/**
* Decodes given sequence of nibbles into a sequence of octets.
*
* @param encoded the nibbles to decode.
*
* @return the decoded octets.
*/
public byte[] decode(final byte[] encoded) {
return decodeMultiple(encoded);
}
C'est un moyen très rapide. Aucune bibliothèque externe nécessaire.
final protected static char[] HEXARRAY = "0123456789abcdef".toCharArray();
public static String encodeHexString( 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);
}
Je ne pouvais pas comprendre ce que vous entendiez exactement par byte String, mais voici quelques conversions d'octet en String et vice versa, bien sûr, il y a beaucoup plus sur les documentations officielles
Integer intValue = 149;
La valeur d'octet correspondante est:
Byte byteValue = intValue.byteValue(); // this will convert the rightmost byte of the intValue to byte, because Byte is an 8 bit object and Integer is at least 16 bit, and it will give you a signed number in this case -107
récupère la valeur entière d'une variable Byte:
Integer anInt = byteValue.intValue(); // This will convert the byteValue variable to a signed Integer
From Byte and Integer to hex String:
Voici comment je le fais:
Integer anInt = 149
Byte aByte = anInt.byteValue();
String hexFromInt = "".format("0x%x", anInt); // This will output 0x95
String hexFromByte = "".format("0x%x", aByte); // This will output 0x95
Conversion d'un tableau d'octets en une chaîne hexadécimale:
Autant que je sache, il n'y a pas de fonction simple pour convertir tous les éléments d'un tableau de certains Object
en éléments d'un autre Object
, vous devez donc le faire vous-même. Vous pouvez utiliser les fonctions suivantes:
De l'octet [] à la chaîne:
public static String byteArrayToHexString(byte[] byteArray){
String hexString = "";
for(int i = 0; i < byteArray.length; i++){
String thisByte = "".format("%x", byteArray[i]);
hexString += thisByte;
}
return hexString;
}
Et de la chaîne hexadécimale à l'octet []:
public static byte[] hexStringToByteArray(String hexString){
byte[] bytes = new byte[hexString.length() / 2];
for(int i = 0; i < hexString.length(); i += 2){
String sub = hexString.substring(i, i + 2);
Integer intVal = Integer.parseInt(sub, 16);
bytes[i / 2] = intVal.byteValue();
String hex = "".format("0x%x", bytes[i / 2]);
}
return bytes;
}
Il est trop tard mais j'espère que cela pourra en aider d'autres;)
Voici votre méthode rapide:
private static final String[] hexes = new String[]{
"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF"
};
public static String byteToHex(byte b) {
return hexes[b&0xFF];
}
Tout comme certaines autres réponses, je recommande d'utiliser String.format()
et BigInteger
. Mais pour interpréter le tableau d'octets comme une représentation binaire big-endian au lieu d' une représentation binaire complémentaire à deux (avec signum et utilisation incomplète de la plage de valeurs hexadécimales possible), utilisez BigInteger (int signum, byte [] magnitude) , pas BigInteger (byte [] val ) .
Par exemple, pour un tableau d'octets de longueur 8, utilisez:
String.format("%016X", new BigInteger(1,bytes))
Avantages:
Désavantage:
Exemple:
byte[] bytes = new byte[8];
Random r = new Random();
System.out.println("big-endian | two's-complement");
System.out.println("-----------------|-----------------");
for (int i = 0; i < 10; i++) {
r.nextBytes(bytes);
System.out.print(String.format("%016X", new BigInteger(1,bytes)));
System.out.print(" | ");
System.out.print(String.format("%016X", new BigInteger(bytes)));
System.out.println();
}
Exemple de sortie:
big-endian | two's-complement
-----------------|-----------------
3971B56BC7C80590 | 3971B56BC7C80590
64D3C133C86CCBDC | 64D3C133C86CCBDC
B232EFD5BC40FA61 | -4DCD102A43BF059F
CD350CC7DF7C9731 | -32CAF338208368CF
82CDC9ECC1BC8EED | -7D3236133E437113
F438C8C34911A7F5 | -BC7373CB6EE580B
5E99738BE6ACE798 | 5E99738BE6ACE798
A565FE5CE43AA8DD | -5A9A01A31BC55723
032EBA783D2E9A9F | 032EBA783D2E9A9F
8FDAA07263217ABA | -70255F8D9CDE8546
Utilisation
Integer.toHexString((int)b);