【问题标题】:String to byte array and then to MD5 in Java字符串到字节数组,然后到 Java 中的 MD5
【发布时间】:2011-12-17 08:32:33
【问题描述】:

在过去的 5 个小时里,我试图做一些应该非常简单的事情,并且在 C# 中只用了 10 分钟就完成了,但在 Java 中没有运气。 我有一个 32 大写和数字字符串 (A-Z0-9),我需要将此字符串转换为 Dec,然后 md5 它。 我的问题是我没有 unsgined 字节,所以我不能 md5 我的数组:\

这是我需要在 python 中做的事情:

salt = words[1].decode("hex")
passwordHash = generatePasswordHash(salt, pw)
generatePasswordHash(salt, password):
    m = md5.new()
    m.update(salt)
    m.update(password)
    return m.digest()

这里是 C# :

public static string GeneratePasswordHash(byte[] a_bSalt, string strData) {
    MD5 md5Hasher = MD5.Create();

    byte[] a_bCombined = new byte[a_bSalt.Length + strData.Length];
    a_bSalt.CopyTo(a_bCombined, 0);
    Encoding.Default.GetBytes(strData).CopyTo(a_bCombined, a_bSalt.Length);

    byte[] a_bHash = md5Hasher.ComputeHash(a_bCombined);

    StringBuilder sbStringifyHash = new StringBuilder();
    for (int i = 0; i < a_bHash.Length; i++) {
        sbStringifyHash.Append(a_bHash[i].ToString("X2"));
    }

    return sbStringifyHash.ToString();
}

protected byte[] HashToByteArray(string strHexString) {
    byte[] a_bReturn = new byte[strHexString.Length / 2];

    for (int i = 0; i < a_bReturn.Length; i++) {
        a_bReturn[i] = Convert.ToByte(strHexString.Substring(i * 2, 2), 16);
    }

    return a_bReturn;
}

我很乐意在这方面得到帮助 :)

【问题讨论】:

  • Java 还是 Python?你让它有点混乱。
  • 我认为 Python 是他的源语言。他正在尝试转换为 Java/C#,但不能转换为 Java。
  • 我正在尝试将上面的 Phyton 和 C# 代码转换成 Java,这是我现在学习的 [Java]
  • 什么是'32 UpperCase and Numeric String (A-Z0-9)'?

标签: java hex md5


【解决方案1】:

将十六进制字符串解析为字节:(byte) Integer.parseInt(s, 16)

要将您的密码字符串转换为字节数组,使用默认编码(我建议不要这样做:始终指定特定编码):password.getBytes()(或 password.getBytes(encoding) 用于特定编码)。

散列一个字节数组:MessageDigest.getInstance("MD5").digest(byte[])

要将字节转换为十六进制字符串:请参阅In Java, how do I convert a byte array to a string of hex digits while keeping leading zeros?

【讨论】:

  • 已经尝试了以上所有方法,但没有成功,因为 246 的无符号字节变成了 -10,它改变了我的最终哈希值。
  • 一个字节就是一个字节。无论它被视为负数还是正数都不会改变其内部位序列。它不应该改变你的最终哈希。为什么不向我们展示您的 Java 代码?
  • pastebin.com/q41uYJL4 - 正如你所看到的,我想通了,它的工作原理和假设一样 :) 感谢您的帮助。
【解决方案2】:

我相信类似以下的方法会起作用:

// convert your hex string to bytes
BigInteger bigInt = new BigInteger(salt, 16);
byte[] bytes = bigInt.toByteArray();
// get the MD5 digest library
MessageDigest md5Digest = null;
try {
    md5Digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
    // error handling here...
}
// by default big integer outputs a 0 sign byte if the first bit is set
if (bigInt.testBit(0)) {
    md5Digest.update(bytes, 1, bytes.length - 1);
} else {
    md5Digest.update(bytes);
}
// get the digest bytes
byte[] digestBytes = md5Digest.digest();

这里有更多关于将十六进制字符串转换为byte[] 数组的想法:

【讨论】:

  • 请看这里,pastebin.com/gxFT55rt - 我写了我在工作 Python 应用程序中测试的结果应该是什么。
  • 已经找到了您可以在上面看到的广告,无论如何感谢您的帮助。
  • 我的代码的问题是,如果第一个字符设置了高位,BigInteger 在前面添加了一个前导字节 0。我现在已经修好了。
【解决方案3】:

您可以在 java 中使用无符号数并应用位掩码。看看详情here

【讨论】:

  • 不会帮助我,因为我不能 md5 字符数组。
猜你喜欢
  • 2014-04-07
  • 2011-10-04
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-22
  • 2014-07-04
相关资源
最近更新 更多