0

JavaでMessageDigestを使用してMD5ハッシュコードを生成しようとしています。以下のサンプルコードを見つけてください。私が試している文字列は、いくつかのコード(KO00001)とシステム日付と組み合わされています。

String s = "KO00001"+"25/10/2012";
byte[] buffer = s.getBytes();
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(buffer);
String str = new BigInteger(1,md5.digest()).toString(16).toUpperCase();
System.out.println(str+"    length:"+str.length());

KO0000126 / 10/2012、KO0000126/10/2012のようなすべての文字列の長さを32にしています。ただし、文字列「KO0000125 / 10/2012」の場合、結果の長さは31になります。

理由は何でしょうか?

4

3 に答える 3

4

org.apache.commons.codec.digest.DigestUtils.md5Hex()このタスクをお勧めします。

于 2012-10-25T09:10:24.363 に答える
3

これは、を使用してハッシュコードのバイト配列表現から取得する数値が、他の数値よりもBigInteger1桁少ないためです。つまり、この表現の最初の(上位)桁はですZERO。比較してください:

KO0000125/10/2012:
10 radix: 14105476919805249323079848858308382190    length:38
16 radix: A9C9DB4AA1D19A4126E63A7ECFD0DEE    length:31

KO0000124/10/2012:
10 radix: 132805232305710448716177011414649345991    length:39
16 radix: 63E95B7C6574B57A3FD202484D0D17C7    length:32

KO0000126/10/2012:
10 radix: 256722737628903394348650044729556126214    length:39
16 radix: C123003325E6846E04656C2F3E7ECA06    length:32
于 2012-10-25T09:19:37.900 に答える
2

md5.digest() 16バイトです

次に、32文字の16進文字列として出力しようとしているのではないかと思います。

その目的のために、あなたは次のようなことをするべきです。

public static String toHexString(byte[] bytes) {
    if (bytes == null) {
        throw new IllegalArgumentException("byte array must not be null");
    }
    StringBuffer hex = new StringBuffer(bytes.length * 2);
    for (int i = 0; i < bytes.length; i++) {
        hex.append(Character.forDigit((bytes[i] & 0XF0) >> 4, 16));
        hex.append(Character.forDigit((bytes[i] & 0X0F), 16));
    }
    return hex.toString();
}

そしてその結果はd41d8cd98f00b204e9800998ecf8427e

(編集1:またはTichodromaが提案したように:車輪の再発明をしないで、Apache Commonsコーデックを使用してください。実際、これらの質問の多くに対する答えは「最初にApache Commonsをチェックする」です)

(編集2:エンコーディングを指定せずにgetBytes()を使用しないでください)

于 2012-10-25T09:12:35.113 に答える