Creazione di una stringa ISO-8859-1 da una stringa HEX in Java, spostamento dei bit
-
06-07-2019 - |
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:
- Esiste un modo più semplice (preferibilmente senza gestione dei bit) per eseguire questa conversione?
- 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
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);
Esiste un modo più semplice (preferibilmente senza gestione dei bit) per fare questo conversione?
Puoi utilizzare Hex classe in beni comuni Apache, ma internamente farà la stessa cosa, forse con differenze minori.
Come devo interpretare la linea:
int value = (high << 4) | low;
?
Questo combina due cifre esadecimali, ognuna delle quali rappresenta 4 bit, in un valore di 8 bit senza segno memorizzato come int
. Le due righe successive lo convertono in un Java byte
.