在java中生成MD5字符串

时间:2014-12-24 19:32:03

标签: java c# .net md5 hashcode

我尝试在java中编写md5字符串。我写了一些代码,我可以添加md5字符串,但我有问题 我第一次给你看我的代码

public class MD5Hash
{

    public static void main(String args[])
    {

        computeMD5Hash("dbox#service" + "2014-12-24T18:34:49");
    }

    public static void computeMD5Hash(String password)
    {
        try
        {
            // Create MD5 Hash
            MessageDigest digest = java.security.MessageDigest.getInstance("MD5");

            digest.update(password.getBytes("UTF-16"));
            digest.update(password.getBytes());

            byte messageDigest[] = digest.digest();
            StringBuffer MD5Hash = new StringBuffer();

            for (int i = 0; i < messageDigest.length; i++)
            {
                String h = Integer.toHexString(0xFF & messageDigest[i]);

                while (h.length() < 2)
                    h = "0" + h;

                MD5Hash.append(h);
            }

            // result.setText("MD5 hash generated is: " + " " + MD5Hash);
            System.out.println("MD5 hash generated is: " + " " + MD5Hash);

        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
    }
}

正如我所说,我可以回复md5字符串,但我的朋友是.net开发人员,他还编写代码,我的md5字符串是不同的。这是他的C#代码

 public static string CreateMD5(string plain)
 {
     MD5 md5 = MD5.Create();
     byte[] inputBytes = Encoding.Unicode.GetBytes(plain);
     byte[] hashBytes = md5.ComputeHash(inputBytes);
     StringBuilder sb = new StringBuilder();

    for (int i = 0; i < hashBytes.Length; i++)
    {
        sb.Append(hashBytes[i].ToString("x2"));
    }

    return sb.ToString();
}
在我的Java代码中,somethink是错误的,因为我希望我的Md5字符串发送服务器,当我将md5字​​符串发送到服务器时我有错误 - 我的朋友没有... 如果有人知道解决方案,我的代码有什么问题请帮助我 感谢

2 个答案:

答案 0 :(得分:1)

On C#sample Encoding.Unicode为您提供UTF-16字符串传递给摘要,而在Java端,UTF-8字符串传递给digest。

答案 1 :(得分:0)

区别的原因:编码

程序之间的区别在于用于将String的字符转换为字节的编码。

C#程序使用UTF-16LE

您朋友的C#程序正在使用Encoding.Unicode.GetBytes(),默认为UTF-16LE,因此生成ea15fbcf2123906e6fcb9f2a3b243492

Java程序使用了其他东西

您的Java程序正在使用String.getBytes(),默认为您当前的Locale编码(可能类似于UTF-8Windows-1252,但显然向后兼容US-ASCII-7 1}})因此产生70F00E5BD872BD73EC6A8B4B8C8C9FEF

同意某事

您必须决定实际应该使用哪种编码。我说对于此类用例,使用UTF-8是最常见的,并建议您同意UTF-8。但无论如何,你需要就某事达成一致。

如何在Java

中使用特定编码,如UTF-8UTF-16LE

替换

digest.update(password.getBytes());

digest.update(password.getBytes(StandardCharsets.UTF_16LE));

digest.update(password.getBytes(StandardCharsets.UTF_8));

您还可以使用超出StandardCharsets中定义的字符集。在这种情况下,您需要使用String的{​​{1}}参数版本并处理String.getBytes(),如下所示:

UnsupportedEncodingException

程序的更好版本

  • try { digest.update(password.getBytes("ISO-8859-15")); } catch (final UnsupportedEncodingException e) { throw new AssertionError(e); } 使用 varargs ,以便在测试时使用main()代替Md5Sum.main()进行调用。
  • Md5Sum.main(new String[0]);重构为print
  • 使用return将字节转换为十六进制Formatter,因为它更方便:它使用的StringStringBuilder快,并且它提供了StringBuffer方法,使转换更加简单。
  • 创建变量format()因为我们打算永远不会重新分配它们。
  • final - 循环替换为for - 循环,因为我们不使用索引变量。
  • 不是打印堆栈跟踪并继续,我们说我们希望foreach可用,如果不是,则是我们程序的内部错误并且中止。坠毁的程序造成的伤害要小于瘫痪程序。
MD5

甚至更好的程序版本

  • 将功能拆分为多个功能,以便可以单独使用(测试,重复使用)。
public class Md5Sum {
    public static void main(final String... args) {
        final String md5sum = md5sum("dbox#service" + "2014-12-24T18:34:49");
        System.out.println("MD5 hash generated is: " + md5sum);
    }
    public static String md5sum2(final String plaintext) {
        try {
            final Formatter formatter = new Formatter();
            final MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(plaintext.getBytes(StandardCharsets.UTF_16LE));
            for (final byte b : digest.digest())
                formatter.format("%02x", b);
            return formatter.toString();
        } catch (final NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        }
    }
}