Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MD5在Java中生成31个字符的哈希_Java_Encoding_Hash_Md5 - Fatal编程技术网

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

MD5在Java中生成31个字符的哈希,java,encoding,hash,md5,Java,Encoding,Hash,Md5,我使用以下代码块生成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

我使用以下代码块生成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;
}
当我使用字符串数据运行上面的代码段时,如
[12,B006GQIIEM,MH-ANT2000]
,输出是一个31个字符的哈希-
268d43a823933c9dafaa4ac0e756d6a


MD5哈希函数有问题吗?或者上面的代码有问题吗?

我就是这样使用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);
 } 
} 
import java.io.UnsupportedEncodingException;
导入java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
公共类MySimpleMD5{
私有静态字符串convertToHex(字节[]数据){
StringBuffer buf=新的StringBuffer();
对于(int i=0;i>>4)&0x0F;
int two_halfs=0;
做{

如果((0代码中唯一的问题是when小于Ox10,则结果哈希字符串将只有31个字节,而不是32个字节,缺少前导零

以以下方式创建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);
            }
byte messageDigest[]=m.digest();
hexString=新的StringBuffer();
对于(int i=0;i您可以尝试以下方法:

...
String digest = String.format("%032x", new BigInteger(1, m.digest()));
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);
}
注意:它是
%032x”
,而不是
%32x”

您也可以尝试以下方法:

...
String digest = String.format("%032x", new BigInteger(1, m.digest()));
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);
}
私有静态字符串getMd5Hash(字符串输入)抛出NoSuchAlgorithmException{
MessageDigest m=MessageDigest.getInstance(“MD5”);
byte[]data=m.digest(EncodingUtils.getBytes(输入,“UTF8”);
StringBuilder sBuilder=新StringBuilder();
对于(int i=0;i
我刚发现一开始有一个
0
被跳过了。我试过在线MD5生成器,它也给出了与
0268d43a823933c9dafaa4ac0e756d6a
相同的结果。每次散列长度不是32时,我是否需要在
0
前面加前缀?您的输入是
[12,B006GQIIEM,MH-ANT2000]
?但当我尝试输入如上所述的输入时,它会使我的输出成为game me output
A722CCBF56BF1FCF579E70D4B2CE721F
32字节
。是的。大括号是输入的一部分。那么,为什么我会像上面所说的那样使用您的代码获得32位编码的文本?您的版本工作正常。您知道早期代码中的问题是什么吗?回答得很好,但我认为这并不能满足提问者的要求。您的版本返回一个完全不同的哈希值-
d41d8cd98f00b204e9800998ecf8427e
。谢谢。但我从接触Java的那天起就一直在使用它。@divinedragon对我有效。我复制了您的代码,然后用这行代码替换了它。所以这只是额外的一行<代码> 0 如果哈希长度为31,我需要用<代码> 0代码/代码>对其进行前缀。这是正确的吗?@ DeViNoDoLo不需要添加另外的“0”。您必须检查每个字符长度并在该特定位置附加“0”。“0”可以在字符串中间添加。您可以在代码中看到我正在检查每一个字符串长度。并附加“0”。@rizzz86:抱歉,您的评论有误导性,因为它与OP的代码无关,而是与您的代码有关。他使用了
.toString(16)
如果生成正确的十六进制表示,它不会忘记在十六进制字符串中添加零-它只会丢弃前导零。因此OP最好在前缀中添加获得32字节字符串所需的数量的零。这段代码如何
for(byte b:digest){sb.append(string.format(“%02x”,b&0xff));}
与您的不同…?哪一个更好。。?