Création d'une chaîne ISO-8859-1 à partir d'une chaîne HEX en Java, décalage de bits
-
06-07-2019 - |
Question
J'essaie de convertir une séquence HEX en une chaîne codée au format ISO-8859-1, UTF-8 ou UTF-16BE. C'est-à-dire que j'ai une chaîne ressemblant à: "0422043504410442"
elle représente les caractères: "Test"
en UTF-16BE.
Le code que j'ai utilisé pour convertir entre les deux formats était le suivant:
private static String hex2String(String hex, String encoding) throws UnsupportedEncodingException {
char[] hexArray = hex.toCharArray();
int length = hex.length() / 2;
byte[] rawData = new byte[length];
for(int i=0; i<length; i++){
int high = Character.digit(hexArray[i*2], 16);
int low = Character.digit(hexArray[i*2+1], 16);
int value = (high << 4) | low;
if( value > 127)
value -= 256;
rawData[i] = (byte) value;
}
return new String(rawData, encoding);
}
Cela semble bien fonctionner pour moi, mais j'ai encore deux questions à ce sujet:
- Existe-t-il un moyen plus simple (de préférence sans traitement des bits) d'effectuer cette conversion?
- Comment dois-je interpréter la ligne:
int value = (high << 4) | low;
?
Je connais les bases de la gestion des bits, mais pas du tout la syntaxe Java. Je crois que la première partie décale tous les bits vers la gauche de 4 pas. Bien que le reste, je ne comprends pas et pourquoi cela serait utile dans cette situation.
Je m'excuse pour la confusion dans ma question, s'il vous plaît laissez-moi savoir si je devrais clarifier quelque chose. Je vous remercie. // Abeansits
La solution
Existe-t-il un moyen plus simple (de préférence sans traitement des bits) d'effectuer cette conversion?
Aucune, à ma connaissance - la seule simplification semble analyser l’octet entier en une fois plutôt que d’analyser chiffre par chiffre (par exemple, avec int value = Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
)
public static byte[] hexToBytes(final String hex) {
final byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
}
return bytes;
}
Comment interpréter la ligne: int value = (high < < 4) | faible;
regardez cet exemple pour vos deux derniers chiffres (42):
int high = 4; // binary 0100
int low = 2; // binary 0010
int value = (high << 4) | low;
int value = (0100 << 4) | 0010; // shift 4 to left
int value = 01000000 | 0010; // bitwise or
int value = 01000010;
int value = 66; // 01000010 == 0x42 == 66
Autres conseils
Vous pouvez remplacer les <<
et |
dans ce cas par *
et +
, mais je ne le recommande pas.
L'expression
int value = (high << 4) | low;
est équivalent à
int value = high * 16 + low;
La soustraction de 256 pour obtenir une valeur comprise entre -128 et 127 est inutile. Par exemple, si vous convertissez 128 en octet, le résultat sera correct. Les 8 bits les plus bas du int
128 ont le même modèle que le byte
-128: 0x80.
Je l'écrirais simplement comme suit:
rawData[i] = (byte) ((high << 4) | low);
Existe-t-il un moyen plus simple (de préférence sans manipulation) pour le faire conversion?