当前位置:  开发笔记 > 编程语言 > 正文

如何生成MD5哈希?

如何解决《如何生成MD5哈希?》经验,为你挑选了23个好方法。

是否有任何方法可以在Java中生成字符串的MD5哈希?



1> koregan..:

MessageDigest班可为您提供的MD5摘要的一个实例.

使用字符串和加密类时,请务必始终指定您希望字节表示的编码.如果您只是使用string.getBytes()它将使用平台默认值.(并非所有平台都使用相同的默认值)

import java.security.*;

..

byte[] bytesOfMessage = yourString.getBytes("UTF-8");

MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);

如果您有大量数据,请查看.update(byte[])可重复调用的方法.然后调用.digest()以获取生成的哈希.


[本主题](http://stackoverflow.com/questions/332079/in-java-how-do-i-convert-a-byte-array-to-a-string-of-hex-digits-while-keeping如果需要将结果字节转换为十六进制字符串,则-l)也很有用.
(有关更好的理由和解释,请参阅http://www.joelonsoftware.com/articles/Unicode.html)
更好的是,尽可能使用`yourString.getBytes(StandardCharsets.UTF_8)`。这样可以防止处理“ UnsupportedEncodingException”。

2> Bombe..:

java.security.MessageDigest是你的朋友.调用MessageDigest.getInstance("MD5")以获取可以使用的MD5消息摘要.


这里没有提到的一件事,让我感到意外.MessageDigest类不是线程安全的.如果它们将被不同的线程使用,只需创建一个新线程,而不是尝试重用它们.
@Bombe:为什么我们应该*了解MessageDigest的内部状态?
它使用多种方法来改变其内部状态.缺乏线程安全性如何令人惊讶?
@DanBarowy好吧,你*正在改变它(即调用不返回值的方法,但导致其他方法返回不同的值),所以除非得到证实,否则你应该总是假设它不是线程安全的.
@Traubenfuchs`MessageDigest`允许您以块的形式输入数据.使用静态方法是不可能的.虽然你可以说他们应该为了方便而添加一个,以便你可以一次传递所有数据.

3> user49913..:

如果您确实希望将答案作为字符串而不是字节数组返回,则可以始终执行以下操作:

String plaintext = "your text here";
MessageDigest m = MessageDigest.getInstance("MD5");
m.reset();
m.update(plaintext.getBytes());
byte[] digest = m.digest();
BigInteger bigInt = new BigInteger(1,digest);
String hashtext = bigInt.toString(16);
// Now we need to zero pad it if you actually want the full 32 chars.
while(hashtext.length() < 32 ){
  hashtext = "0"+hashtext;
}


@BalusC:不正确,BigInteger.toString方法将返回指定基数中的完整数字.0x0606将打印为606,只省略尾随零,
轻微的挑剔:在调用getInstance后不需要m.reset().更轻微:'你的文字在这里'需要双引号.

4> lutzh..:

您可能还想查看apache commons编解码器项目的DigestUtils类,它提供了非常方便的方法来创建MD5或SHA摘要.


应该在中央Maven存储库中,除非我疯了:groupId = commons-codec artifactId = commons-codec version = 1.5
但是,没有简单的方法可以将DigestUtils类放入您的项目中,而无需添加大量的lib,或者"每手"移植类,这需要至少两个类.
特别是,以字符串形式返回字节数据的"安全"编码表示的方法.

5> dac2009..:

发现这个:

public String MD5(String md5) {
   try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(md5.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
          sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
       }
        return sb.toString();
    } catch (java.security.NoSuchAlgorithmException e) {
    }
    return null;
}

在下面的网站上,我不相信它,但它的解决方案有效!对我来说,很多其他代码都没有正常工作,我最终在哈希中丢失了0.这个看起来和PHP一样.来源:http://m2tec.be/blog/2010/02/03/java-md5-hex-0093


您应该指定要在`getBytes()`中使用的编码,否则您的代码将在不同的平台/用户设置上获得不同的结果.
有关字符集的示例...(使用UTF-8,这是我认为最好和最兼容的)...`byte [] array = md.digest(md5.getBytes(Charset.forName("UTF") -8" )));`
@BlazeTama"MD5"不是编码,它是一种消息摘要算法(而不是应该在新应用程序中使用的算法).编码是一种算法对,它将字节转换为字符串,将字符串转换为字节.一个例子是"UTF-8","US-ASCII","ISO-8859-1","UTF-16BE"等.使用与计算此字符串哈希值的每个其他方相同的编码,否则您将得到不同的结果.

6> adranale..:

这是我如何使用它:

final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.reset();
messageDigest.update(string.getBytes(Charset.forName("UTF8")));
final byte[] resultByte = messageDigest.digest();
final String result = new String(Hex.encodeHex(resultByte));

其中Hex是:org.apache.commons.codec.binary.Hex来自Apache Commons项目.


如果你使用Apache Commons Codec,你可以使用:http://commons.apache.org/codec/api-release/org/apache/commons/codec/digest/DigestUtils.html#md5Hex(java.lang.String)
我会用这个替换最后一行:`String result = Hex.encodeHexString(resultByte);`

7> Eugene..:

我刚刚下载了commons-codec.jar并获得了像md5这样的完美php.这是手册.

只需将其导入您的项目并使用即可

String Url = "your_url";

System.out.println( DigestUtils.md5Hex( Url ) );

你有它.



8> rednoah..:

我发现这是最清晰简洁的方法:

MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(StandardCharsets.UTF_8.encode(string));
return String.format("%032x", new BigInteger(1, md5.digest()));



9> Heshan Perer..:

发现这个解决方案在从MD5哈希中获取字符串表示方面更加清晰.

import java.security.*;
import java.math.*;

public class MD5 {
    public static void main(String args[]) throws Exception{
        String s="This is a test";
        MessageDigest m=MessageDigest.getInstance("MD5");
        m.update(s.getBytes(),0,s.length());
        System.out.println("MD5: "+new BigInteger(1,m.digest()).toString(16));
    }
}

代码是从这里提取的.


我刚刚发现,在某些情况下,这只产生31个字符长的MD5总和,而不是32个应有的数字
很高兴使用BigInteger获得十六进制值+1
@kovica这是因为,如果我没记错的话,起始零会被截断.`String.format("%032x",new BigInteger(1,hash));`这应该解决这个问题.'hash'是散列的byte [].
为什么这个答案为-1而另一个,更短且描述性较差的答案为+146?

10> andrewrjones..:

另一种选择是使用Guava Hashing方法:

Hasher hasher = Hashing.md5().newHasher();
hasher.putString("my string");
byte[] md5 = hasher.hash().asBytes();

如果你已经在使用番石榴(如果你不是,你可能应该这样),这很方便.


@KurtAlfredKluever不要忘记插入像'Hashing.md5().hashString("my string",Charsets.UTF_8).asBytes()'这样的字符集
或使用其中一种快捷方法:`Hashing.md5().hashString("my string").asBytes();`

11> stacker..:

另一个实现:

import javax.xml.bind.DatatypeConverter;

String hash = DatatypeConverter.printHexBinary( 
           MessageDigest.getInstance("MD5").digest("SOMESTRING".getBytes("UTF-8")));


我见过的只有一行不使用外部库.
@ walshie4没有没有hex的MD5(参见http://www.ietf.org/rfc/rfc1321.txt),只需添加.toLower()即可获得小写.将结果与例如https://en.wikipedia.org/wiki/MD5中的示例进行比较,您将有更好的机会相信Javas库代码是正确的.

12> fitorec..:

我有一个Class(Hash)来转换格式为hash的纯文本:md5或sha1,simillar php函数(md5,sha1):

public class Hash {
    /**
     * 
     * @param txt, text in plain format
     * @param hashType MD5 OR SHA1
     * @return hash in hashType 
     */
    public static String getHash(String txt, String hashType) {
        try {
                    java.security.MessageDigest md = java.security.MessageDigest.getInstance(hashType);
                    byte[] array = md.digest(txt.getBytes());
                    StringBuffer sb = new StringBuffer();
                    for (int i = 0; i < array.length; ++i) {
                        sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3));
                 }
                    return sb.toString();
            } catch (java.security.NoSuchAlgorithmException e) {
                //error action
            }
            return null;
    }

    public static String md5(String txt) {
        return Hash.getHash(txt, "MD5");
    }

    public static String sha1(String txt) {
        return Hash.getHash(txt, "SHA1");
    }
}

使用JUnit和PHP进行测试

PHP脚本:



输出PHP脚本:

MD5 :b10a8db164e0754105b7a99be72e3fe5
SHA1:0a4d55a8d778e5022fab701977c5d840bbc486d0

使用示例和使用JUnit进行测试:

    public class HashTest {

    @Test
    public void test() {
        String txt = "Hello World";
        assertEquals("b10a8db164e0754105b7a99be72e3fe5", Hash.md5(txt));
        assertEquals("0a4d55a8d778e5022fab701977c5d840bbc486d0", Hash.sha1(txt));
    }

}

GitHub中的代码

https://github.com/fitorec/java-hashes



13> marioosh..:

我不是很有启发性的答案:

private String md5(String s) {
    try {
        MessageDigest m = MessageDigest.getInstance("MD5");
        m.update(s.getBytes(), 0, s.length());
        BigInteger i = new BigInteger(1,m.digest());
        return String.format("%1$032x", i);         
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return null;
}



14> Fatih Karata..:

不需要太复杂.DigestUtils工作正常,在使用md5哈希时让您感觉舒适.

DigestUtils.md5Hex(_hash);

要么

DigestUtils.md5(_hash);

您可以使用任何其他加密方法,如sha或md.



15> Raul Luna..:

Spring中还有一个DigestUtils类:

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/util/DigestUtils.html

该类包含md5DigestAsHex()执行该作业的方法.



16> frankodwyer..:

Bombe的答案是正确的,但是请注意,除非你绝对必须使用MD5(例如强迫你使用互操作性),否则更好的选择是SHA1,因为MD5具有长期使用的弱点.

我应该补充一点,SHA1也有理论上的漏洞,但并不严重.散列的当前技术水平是有许多候选替换散列函数,但尚未出现作为替换SHA1的标准最佳实践.因此,根据您的需求,建议您将哈希算法配置为可以在将来进行替换.


除非您需要加密安全散列,否则SHA1过度杀戮,即您不希望散列有助于重建原始消息,您也不希望聪明的攻击者创建与散列匹配的另一条消息.如果原始版本不是秘密并且哈希不用于安全性,则MD5快速而简单.例如,Google Web Toolkit在JavaScript URL中使用MD5哈希(例如foo.js?hash = 12345).

17> ylu..:

你可以尝试以下.请在此处查看详细信息和下载代码:http://jkssweetlife.com/java-hashgenerator-md5-sha-1/

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Example {

public static void main(String[] args) throws Exception {

    final String inputString = "Hello MD5";

    System.out.println("MD5 hex for '" + inputString + "' :");
    System.out.println(getMD5Hex(inputString));
}

public static String getMD5Hex(final String inputString) throws NoSuchAlgorithmException {

    MessageDigest md = MessageDigest.getInstance("MD5");
    md.update(inputString.getBytes());

    byte[] digest = md.digest();

    return convertByteToHex(digest);
}

private static String convertByteToHex(byte[] byteData) {

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < byteData.length; i++) {
        sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
    }

    return sb.toString();
}
}



18> Lukasz R...:

另一个实现:Java中的快速MD5实现

String hash = MD5.asHex(MD5.getHash(new File(filename)));



19> kriegaex..:

我不知道这是否适合任何阅读此内容的人,但我只是遇到了我想要的问题

从给定的URL下载文件

将其MD5与已知值进行比较.

我只想用JRE类(没有Apache Commons或类似的)来做.快速网络搜索没有向我显示示例代码片段同时执行这两个操作,仅分别执行每个任务.因为这需要两次读取相同的文件,我认为编写一些统一两个任务的代码可能是值得的,在下载文件时动态计算校验和.这是我的结果(对不起,如果它不是完美的Java,但我想你无论如何都会得到这个想法):

import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.security.DigestOutputStream;        // new
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

void downloadFile(String fromURL, String toFile, BigInteger md5)
    throws IOException, NoSuchAlgorithmException
{
    ReadableByteChannel in = Channels.newChannel(new URL(fromURL).openStream());
    MessageDigest md5Digest = MessageDigest.getInstance("MD5");
    WritableByteChannel out = Channels.newChannel(
        //new FileOutputStream(toFile));  // old
        new DigestOutputStream(new FileOutputStream(toFile), md5Digest));  // new
    ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);  // 1 MB

    while (in.read(buffer) != -1) {
        buffer.flip();
        //md5Digest.update(buffer.asReadOnlyBuffer());  // old
        out.write(buffer);
        buffer.clear();
    }

    BigInteger md5Actual = new BigInteger(1, md5Digest.digest()); 
    if (! md5Actual.equals(md5))
        throw new RuntimeException(
            "MD5 mismatch for file " + toFile +
            ": expected " + md5.toString(16) +
            ", got " + md5Actual.toString(16)
        );
}



20> 小智..:

看一下以下链接,Example获取一个提供的图像的MD5哈希:MD5图像 哈希



21> Mihai Danila..:

对于它的价值,我偶然发现了这一点,因为我想从一个自然键中合成GUID来安装COM组件的程序; 我想syhthesize以便不管理GUID生命周期.我将使用MD5,然后使用UUID类从中获取字符串.(http://stackoverflow.com/questions/2190890/how-can-i-generate-guid-for-a-string-values/12867439引发了这个问题).

在任何情况下,java.util.UUID都可以从MD5字节中获得一个很好的字符串.

return UUID.nameUUIDFromBytes(md5Bytes).toString();



22> 小智..:

如果你不需要最好的安全性,MD5是完全正常的,如果你正在做类似检查文件完整性的事情,那么安全性不是一个考虑因素.在这种情况下,您可能需要考虑更简单和更快速的事情,例如Adler32,它也受Java库支持.


是什么让你认为文件完整性不是安全问题?

23> Giancarlo Ro..:
import java.security.*;
import javax.xml.bind.*;

byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] bytesOfDigest = md.digest(bytesOfMessage);
String digest = DatatypeConverter.printHexBinary(bytesOfDigest).toLowerCase();

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有