31

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 <=digit < 基数の場合、数字の引数は有効です。

2 つの方法の違いと、先頭の 0 が削除される理由を教えてください。

4

5 に答える 5

22

個人的には、バイナリ データをテキストに変換するために使用することは避けたいと思います。そのために使用できるBigIntegerとしても、それは実際にはそこにあるものではありません。aを 16 進表現に変換するために利用できるコードがたくさんあります。たとえば、 Apache Commons Codecまたは単純な単一の方法を使用します。byte[]

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);
}
于 2012-04-23T06:33:13.757 に答える
12

String.format("%064X", new BigInteger(1, ByteArray);

どこ

  1. 0 - 先行符号ゼロ
  2. 64 - 文字列の長さ
  3. X - 大文字
  4. ByteArray - この操作を実行する ByteArray
于 2016-01-12T14:39:24.983 に答える
9

によると、先頭のゼロは重要ではないため、削除されていBigIntegerます。27と の間に違いはありません000000000027

特定の長さが必要な場合は、次のように自分で強制する必要があります。

output = ("00000000000000000000000000000000"+output).substring(output.length());

(それは不器用ですが)。

于 2012-04-23T06:33:46.067 に答える
2

削除されたゼロは、次のコードを使用して置き換えられます。

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;
    }

ループは、必要な数の先行ゼロを考慮します

于 2012-09-26T14:54:25.793 に答える