MessageDigestを使用してMD5合計を生成しようとしています。そして、私は次のコードを持っています。
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);
これは、32文字の文字列ではなく、31文字の文字列を返します8611c0b0832bce5a19ceee626a403a7
期待される文字列は08611c0b0832bce5a19ceee626a403a7
先頭の0が出力にありません。
私は他の方法を試しました
byte[] md5sum = digest.digest();
output = new String(Hex.encodeHex(md5sum));
そして、出力は期待どおりです。
ドキュメントを確認すると、Integer.toStringがそれに応じて変換を行います
Character.forDigitによって提供される数字から文字へのマッピングが使用され、必要に応じてマイナス記号が付加されます。
およびCharacter.forDigitメトス
桁引数は、0 <=桁<基数の場合に有効です。
2つの方法の違いと、先頭の0が削除される理由を教えてもらえますか?
私は個人的にavoidBigInteger
を使用してバイナリデータをテキストに変換します。 を使用できるとしても、それは実際にはその目的ではありません。 byte[]
を16進表現に変換するために利用できるコードがたくさんあります。 Apache Commons Codec または単純な単一の方法を使用します。
private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
public static String toHex(byte[] data) {
char[] chars = new char[data.length * 2];
for (int i = 0; i < data.length; i++) {
chars[i * 2] = HEX_DIGITS[(data[i] >> 4) & 0xf];
chars[i * 2 + 1] = HEX_DIGITS[data[i] & 0xf];
}
return new String(chars);
}
BigInteger
によると、先行ゼロは重要ではないため、削除されています。 27
と000000000027
の間に違いはありません。
特定の長さが必要な場合は、次のように自分で強制する必要があります。
output = ("00000000000000000000000000000000"+output).substring(output.length());
(それは厄介ですが)。
String.format( "%064X"、new BigInteger(1、hmac.doFinal(message.getBytes())));
どこ
削除されたゼロは、次のコードを使用して置き換えられます。
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(output.getBytes());
byte[] outDigest = digest.digest();
BigInteger outBigInt = new BigInteger(1,outDigest);
output = outBigInt.toString(16);
while (output.length() < 32){
output = "0"+output;
}
ループは必要な数の先行ゼロを考慮します