Domanda

Sto cercando di convertire una sequenza HEX in una stringa codificata in ISO-8859-1, UTF-8 o UTF-16BE. Cioè, ho una stringa che assomiglia a: "0422043504410442" questo rappresenta i caratteri: "Test" in UTF-16BE.

Il codice che ho usato per convertire tra i due formati era:

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);
}

Questo sembra funzionare bene per me, ma ho ancora due domande al riguardo:

  1. Esiste un modo più semplice (preferibilmente senza gestione dei bit) per eseguire questa conversione?
  2. Come devo interpretare la linea: int value = (high << 4) | low;?

Conosco le basi della gestione dei bit, anche se per nulla con la sintassi Java. Credo che la prima parte sposta tutti i bit a sinistra di 4 passi. Anche se il resto non capisco e perché sarebbe utile in questa determinata situazione.

Mi scuso per qualsiasi confusione nella mia domanda, per favore fatemi sapere se dovrei chiarire qualcosa. Grazie. // Abeansits

È stato utile?

Soluzione

Esiste un modo più semplice (preferibilmente senza gestione dei bit) per eseguire questa conversione?

Nessuno di cui sarei a conoscenza - l'unica semplificazione sembra analizzare l'intero byte in una sola volta anziché analizzare cifra per cifra (ad esempio utilizzando 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;
}

Come interpretare la riga: int value = (high < < 4) | bassa;?

guarda questo esempio per le ultime due cifre (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

Altri suggerimenti

Puoi sostituire << e | in questo caso con * e +, ma non lo consiglio.

L'espressione

int value = (high << 4) | low;

è equivalente a

int value = high * 16 + low;

La sottrazione di 256 per ottenere un valore compreso tra -128 e 127 non è necessaria. Il semplice lancio, ad esempio, di 128 in un byte produrrà il risultato corretto. Gli 8 bit più bassi di int 128 hanno lo stesso modello di byte -128: 0x80.

Lo scriverei semplicemente come:

rawData[i] = (byte) ((high << 4) | low);
scroll top