MD 5暗号化でbyteを16進数に変換する問題について

2278 ワード

MD 5暗号化でbyteを16進数に変換する問題について


問題の説明


まずMD 5暗号化コードを見てみましょう
StringBuilder builder = new StringBuilder();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(myContentString.getBytes());
byte[] bytes = md.digest();
for(byte b : bytes)
    builder.append(Integer.toString((b & 0xff) + 0x100).subString(1));
String result = builder.toString();

どうして最後から2番目の文をこのように書くのですか.

質問の回答


Javaではbyteがintに変換されると符号付き拡張に従って変換される.例えばbyteが1111_の場合1111であれば、intに変換されると、残りの24ビットはbyteの最上位、すなわちシンボルビットと同じであり、intは32個の1からなる整数となる.明らかにこれは私たちが望んでいるものではありません.0 xffffffではなく0 xffが必要だからです.

じゃあどうして&ちょっとでいいの?


拡張された24ビットを処理するために.まずJavaでは0 xff,123のような非小数の字面量はデフォルトでintタイプであり,byteはこのような字面量と演算し,アップコンバートの原則に従って結果が自動的にintタイプに変換される.第二に、&の特性は、対応ビットが同じで同じで同じで、異なるのが0であり、byteをintに変換したときの最初の24個の充填位置が0になる効果、すなわち最後の8ビットをふるい出す効果を達成することができる.これにより、16進数文字列に変換する際に、上位24ビットの問題を考慮する必要がなくなります.

0 x 100を加えた理由は?


ゼロをリードするために.byteを2ビットの16進数に変換する必要がありますが、byteの高さ4ビットが0であれば出力は1ビットしかありません.byteが0000の場合1111の場合、0 x 100を追加しないと、上のコードはbyteを0 fではなくfに変換します.0 x 100が加算されると、これを例にとると、結果として0 x 10 fとなり、子列を取ることによりindex=1のところから(indexはゼロから)取り始め、0 fを取り出すことができるようになる.

その他のソリューションは


文字列フォーマット操作で、最後から2番目の文を直接書くことができます.
builder.append(String.format("%02x",b));

「%02 x」は、bを2ビットにフォーマットした16進数で、プリアンブルを補うのに足りないことを示します.