Erstellen einen ISO-8859-1 String aus einem HEX-String in Java, Verschieben von Bits
-
06-07-2019 - |
Frage
Ich versuche, eine HEX-Sequenz zu einem String in entweder, ISO-8859-1, UTF-8 oder UTF-16 BE codiert zu konvertieren. Das heißt, ich habe einen String suchen wie: "0422043504410442"
dies stellt die Zeichen:. "Test"
in UTF-16 BE
Der Code, den ich verwenden, um zwischen den beiden Formaten zu konvertieren war:
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);
}
Das scheint gut für mich zu arbeiten, aber ich habe noch zwei Fragen in Bezug auf diese:
- Gibt es eine einfachere Art und Weise (vorzugsweise ohne Bit-Handling), um diese Umwandlung zu tun?
- Wie soll ich die Linie interpretieren:
int value = (high << 4) | low;
Ich bin vertraut mit den Grundlagen der Bit-Handhabung, wenn auch nicht mit der Java-Syntax. Ich glaube, dass der erste Teil von vier Schritten, um alle Bits nach links verschieben. Obwohl der Rest verstehe ich nicht und warum wäre es hilfreich, in dieser bestimmten Situation.
ich für die Verwirrung in meiner Frage entschuldigen, bitte lassen Sie mich wissen, ob ich etwas klarstellen sollte. Danke. // Abeansits
Lösung
Gibt es eine einfachere Art und Weise (vorzugsweise ohne Bit-Handling), um diese Umwandlung zu tun?
Keine ich kenne, würde - die einzige Vereinfachung scheint das ganze Byte auf einmal anstatt Parsen Ziffer für Ziffer (zum Beispiel unter Verwendung von 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;
}
Wie soll ich die Linie interpretieren: int value = (high << 4) | niedrig;?
Blick auf dieses Beispiel für die letzten beiden Ziffern (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
Andere Tipps
Sie können die <<
und |
in diesem Fall mit *
und +
ersetzen, aber ich würde es nicht empfehlen.
Der Ausdruck
int value = (high << 4) | low;
entspricht
int value = high * 16 + low;
Die Subtraktion von 256 einen Wert zwischen -128 zu bekommen und 127 nicht erforderlich ist. Einfach Gießen, beispielsweise 128 zu einem Byte wird das richtige Ergebnis. Die untersten 8 Bits des int
128 das gleiche Muster wie die byte
-128:. 0x80
Ich würde es schreiben einfach wie:
rawData[i] = (byte) ((high << 4) | low);
Gibt es eine einfachere Art und Weise (vorzugsweise ohne Bit-Handling), dies zu tun Umwandlung?
Sie können mit dem Hex Klasse in Apache commons, aber intern wird es das gleiche tun, vielleicht mit kleinen Unterschieden.
Wie soll ich die Linie interpretieren:
int value = (high << 4) | low;
Diese verbindet zwei Hexadezimalziffern, von denen jeder 4 Bits als int
gespeichert sind, in einen unsigned 8-Bit-Wert darstellt. Die nächsten beiden Zeilen wandeln diese in eine signierte Java byte
.