Javaの16進数文字列からISO-8859-1文字列を作成し、ビットをシフトする
-
06-07-2019 - |
質問
HEXシーケンスを、ISO-8859-1、UTF-8、またはUTF-16BEのいずれかでエンコードされた文字列に変換しようとしています。つまり、次のような文字列があります:"0422043504410442"
これは文字を表します:"Test"
UTF-16BE。
2つの形式間の変換に使用したコードは次のとおりです。
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);
}
これは私にとってはうまくいくようですが、これに関してはまだ2つの質問があります:
- この変換を行うためのより簡単な方法(好ましくはビット処理なし)はありますか?
- どのように行を解釈しますか:
int value = (high << 4) | low;
?
私はビット処理の基本に精通していますが、Java構文にはまったく精通していません。最初の部分は、すべてのビットを4ステップ左にシフトすると思います。残りは理解できませんが、なぜこの特定の状況で役立つのでしょうか。
質問にご迷惑をおかけしましたことをおaび申し上げます。明確にする必要がある場合はお知らせください。 ありがとうございました。 // Abeansits
解決
この変換を行うためのより簡単な方法(ビット処理を使用しないことが望ましい)はありますか?
私が知っているだろう-唯一の単純化は、数字ごとに解析するのではなく、バイト全体を一度に解析するようです(たとえば、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;
}
行の解釈方法:int value =(high <!> lt; <!> lt; 4)|低;?
最後の2桁(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
他のヒント
<<
と|
は、この場合*
と+
に置き換えることができますが、お勧めしません。
式
int value = (high << 4) | low;
は同等です
int value = high * 16 + low;
-128〜127の値を得るために256を引く必要はありません。たとえば、128を1バイトにキャストするだけで正しい結果が得られます。 int
128の最下位8ビットは、byte
-128:0x80と同じパターンを持っています。
単純に次のように記述します。
rawData[i] = (byte) ((high << 4) | low);
より簡単な方法はありますか(できれば ビット処理なし)これを行う 変換?
Hex Apache commonsのクラスですが、内部的には同じことを行いますが、おそらくわずかな違いがあります。
どのように行を解釈しますか:
int value = (high << 4) | low;
?
これは、それぞれが4ビットを表す2つの16進数字を、int
として保存される1つの符号なし8ビット値に結合します。次の2行は、これを署名付きJava byte
に変換します。