MD5 在 Java 中生成 31 个字符的哈希

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13411996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:37:30  来源:igfitidea点击:

MD5 Generates 31 character hash in Java

javaencodinghashmd5

提问by divinedragon

I am using following code block to generate MD5 hashes:

我正在使用以下代码块来生成 MD5 哈希:

public static String encode(String data) throws Exception {

    /* Check the validity of data */
    if (data == null || data.isEmpty()) {
        throw new IllegalArgumentException("Null value provided for "
                + "MD5 Encoding");
    }

    /* Get the instances for a given digest scheme MD5 or SHA */
    MessageDigest m = MessageDigest.getInstance("MD5");

    /* Generate the digest. Pass in the text as bytes, length to the
     * bytes(offset) to be hashed; for full string pass 0 to text.length()
     */
    m.update(data.getBytes(), 0, data.length());

    /* Get the String representation of hash bytes, create a big integer
     * out of bytes then convert it into hex value (16 as input to
     * toString method)
     */
    String digest = new BigInteger(1, m.digest()).toString(16);

    return digest;
}

When I run the above code segment with String data as [12, B006GQIIEM, MH-ANT2000], the output is a 31 character hash - 268d43a823933c9dafaa4ac0e756d6a.

当我使用 String data as 运行上面的代码段时[12, B006GQIIEM, MH-ANT2000],输出是一个 31 个字符的哈希 - 268d43a823933c9dafaa4ac0e756d6a

Is there any problem with the MD5 hash function or there is some problem in the code above?

是MD5哈希函数有问题还是上面的代码有问题?

采纳答案by rizzz86

The only issue in your code is when MSBis less than Ox10, the result hash string will only have 31 bytes, instead of 32 bytes, missing the leading zero.

您代码中的唯一问题是当MSB小于 Ox10 时,结果哈希字符串将只有 31 个字节,而不是 32 个字节,缺少前导零。

Create your md5 string in this way:

以这种方式创建您的 md5 字符串:

            byte messageDigest[] = m.digest();

            hexString = new StringBuffer();
            for (int i=0;i<messageDigest.length;i++) {
                String hex=Integer.toHexString(0xFF & messageDigest[i]);
                if(hex.length()==1)
                    hexString.append('0');

                hexString.append(hex);
            }

回答by divinedragon

You can try this:

你可以试试这个:

...
String digest = String.format("%032x", new BigInteger(1, m.digest()));

Note:it is "%032x", not "%32x".

注意:"%032x",不是"%32x"

回答by Yves_T

This is how I use MD5 hash. Calculate MD5 hash from string and return 32-byte hexadecimal representation.

这就是我使用 MD5 哈希的方式。从字符串计算 MD5 哈希值并返回 32 字节的十六进制表示。

import java.io.UnsupportedEncodingException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

public class MySimpleMD5 { 

private static String convertToHex(byte[] data) { 
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < data.length; i++) { 
        int halfbyte = (data[i] >>> 4) & 0x0F;
        int two_halfs = 0;
        do { 
            if ((0 <= halfbyte) && (halfbyte <= 9)) 
                buf.append((char) ('0' + halfbyte));
            else 
                buf.append((char) ('a' + (halfbyte - 10)));
            halfbyte = data[i] & 0x0F;
        } while(two_halfs++ < 1);
    } 
    return buf.toString();
} 

public static String MD5(String text) 
throws NoSuchAlgorithmException, UnsupportedEncodingException  { 
    MessageDigest md;
    md = MessageDigest.getInstance("MD5");
    byte[] md5hash = new byte[32];
    md.update(text.getBytes("iso-8859-1"), 0, text.length());
    md5hash = md.digest();
    return convertToHex(md5hash);
 } 
} 

回答by anTONIos

You can also try this:

你也可以试试这个:

private static String getMd5Hash(String input) throws NoSuchAlgorithmException {
    MessageDigest m = MessageDigest.getInstance("MD5");

    byte[] data = m.digest(EncodingUtils.getBytes(input, "UTF8"));

    StringBuilder sBuilder = new StringBuilder();

    for (int i = 0; i < data.length; i++) {

        for (byte b : data) {
            if(b == 0x00){
                sBuilder.append("00");
            } else if ((b & 0x0F) == b) {
                sBuilder.append("0");
                break;
            } else {
                break;
            }
        }

        BigInteger bigInt = new BigInteger(1, data);
        sBuilder.append(bigInt.toString(16));
    }

    // Return the hexadecimal string.
    return sBuilder.toString().substring(0, 32);
}