【问题标题】:MD5 hash is differentMD5 哈希值不同
【发布时间】:2011-05-17 07:06:46
【问题描述】:

从php到java这几行不知道怎么实现..

$varInHex = "\x22\x33\xAd\xB5\x2b\xE6\x22\x33\x12\x36\x22\x31\xCA\x22\x11\x41\x62\x21\x22\x01\x55\x22\x71\x42\x10\x36";<br/><br/>
$result = md5($varInHex);
echo $result;

好吧,我尝试转换它,但我得到了不同的结果!

byte[] seq20 = new byte[]{(byte)0x22,(byte)...etc...};
String str = seq20.toString();
String result = md5(str);
System.out.println(result);

public static String md5(String source) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = md.digest(source.getBytes("UTF-8"));
        return getString(bytes);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

private static String getString(byte[] bytes) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < bytes.length; i++) {
        byte b = bytes[i];
        String hex = Integer.toHexString((int) 0x00FF & b);
        if (hex.length() == 1) {
            sb.append("0");
        }
        sb.append(hex);
    }
    return sb.toString();
}

java 中的结果与 php 中的结果不同..

你能帮帮我吗? 提前谢谢你:)

【问题讨论】:

    标签: java php string md5 hex


    【解决方案1】:

    你不能直接使用seq20而不把它转换成这样的字符串吗? 我会这样做:

    md.update( seq20 ); 
    byte[] md5sum = md.digest();
    BigInteger bigInt = new BigInteger(1, md5sum);
    output = bigInt.toString(16);
    while ( output.length() < 32 ) {
        output = "0"+output;
    }
    

    【讨论】:

    • 查看@adves 的回答。这是一个很好的教训:如果你能帮上忙,不要把你自己的解决方案用于常见问题,因为你不可避免地会出错。
    • @amalloy 感谢您的提示,我已解决。
    【解决方案2】:

    其他两个答案都不是肯定错误的,但从优雅的角度来看,请考虑以下内容

    String MD5(String... strings) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
            for(final String s : strings) {
                md.update(s.getBytes());
            }
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException("MD5 Cryptography Not Supported");
        }
        final BigInteger bigInt = new BigInteger(1, md.digest());
        return String.format("%032x", bigInt);
    }
    

    编辑:String... varargs 的使用是完全可选的,但它使函数更容易一些,因为它避免了调用函数中字符串连接的开销。

    【讨论】:

    • 我刚刚实现了这个解决方案,我可以说我非常喜欢它。
    【解决方案3】:

    公认的解决方案:

    md.update( seq20 ); 
    byte[] md5sum = md.digest();
    BigInteger bigInt = new BigInteger(1, md5sum);
    output = bigInt.toString(16);
    if ( output.length() == 31 ) {
        output = "0"+output;
    }
    

    包含一个将失败 1/256 次的实现,因为 md5sum 的输出可以有多个前导零。将引发此错误的示例 md5 输入是:“15446:68106”(不带引号)。

    如果您需要与 php 实现匹配的 md5,我建议使用 apache commons DigestUtils.md5Hex。

    【讨论】:

      【解决方案4】:

      我的猜测是 PHP 将上述内容作为字符串进行评估,而不是十六进制。 Java 正在按照您的预期进行操作。

      【讨论】:

        猜你喜欢
        • 2022-01-15
        • 2018-11-08
        • 2013-04-13
        • 1970-01-01
        • 1970-01-01
        • 2014-05-19
        • 2012-08-17
        • 2011-01-13
        相关资源
        最近更新 更多