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:

  1. Existe-t-il un moyen plus simple (de préférence sans traitement des bits) d'effectuer cette conversion?
  2. 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

Était-ce utile?

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);
scroll top