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


当前回答

如果你真的想要返回一个字符串,而不是字节数组,你总是可以这样做:

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;
}

其他回答

我不知道这与阅读这篇文章的人是否相关,但我只是遇到了我想要解决的问题

从给定的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)
        );
}

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

我应该补充一点,SHA1也有理论上的漏洞,但没有那么严重。目前的哈希技术水平是,有许多候选替换哈希函数,但还没有一个成为取代SHA1的标准最佳实践。因此,根据您的需要,建议您使您的哈希算法可配置,以便将来可以替换它。

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();

我有一个类(哈希)在哈希格式转换纯文本:md5或sha1,类似于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

echo 'MD5 :' . md5('Hello World') . "\n";
echo 'SHA1:' . sha1('Hello World') . "\n";

输出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

你可以试试凯撒。

第一选择:

byte[] hash =
    new Hash(
        new ImmutableMessageDigest(
            MessageDigest.getInstance("MD5")
        ),
        new PlainText("String to hash...")
    ).asArray();

第二选择:

byte[] hash =
    new ImmutableMessageDigest(
        MessageDigest.getInstance("MD5")
    ).update(
        new PlainText("String to hash...")
    ).digest();