Javaの16進数文字列からISO-8859-1文字列を作成し、ビットをシフトする

StackOverflow https://stackoverflow.com/questions/1631440

質問

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つの質問があります:

  1. この変換を行うためのより簡単な方法(好ましくはビット処理なし)はありますか?
  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に変換します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top