ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Java 中生成 MD5 哈希?

有没有什么方法可以在 Java 中生成字符串的 MD5 哈希?

MD5 作为一种单向安全功能可能不安全,但它仍然适用于通用校验和应用程序。

r
rogerdpack

MessageDigest 类可以为您提供 MD5 摘要的实例。

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

import java.security.*;

..

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

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

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


“LATIN1”!=“ASCII”(或“US-ASCII”)。 ASCII 是 7 位字符集,Latin1 是 8 位字符集。他们不一样。
(有关更好的理由和解释,请参阅 joelonsoftware.com/articles/Unicode.html
如果您需要将结果字节转换为十六进制字符串,This topic 也很有用。
那么你如何将这个 thedigest 转换为一个字符串,以便我们可以将它插入到 mysql 中?
更好的是,尽可能使用 yourString.getBytes(StandardCharsets.UTF_8)。这可以防止处理 UnsupportedEncodingException
M
MultiplyByZer0

您需要 java.security.MessageDigest

调用 MessageDigest.getInstance("MD5") 以获取您可以使用的 MessageDigest 的 MD5 实例。

通过执行以下操作之一计算哈希:

将整个输入作为 byte[] 提供,并使用 md.digest(bytes) 在一次操作中计算散列。

通过调用 md.update(bytes) 一次向 MessageDigest 提供一个 byte[] 块。添加完输入字节后,使用 md.digest() 计算散列。

md.digest() 返回的 byte[] 是 MD5 哈希。


这里没有提到的一件事让我感到惊讶。 MessageDigest 类不是线程安全的。如果它们将被不同的线程使用,只需创建一个新线程,而不是尝试重用它们。
它使用多种方法来改变其内部状态。缺乏线程安全性怎么会令人惊讶呢?
@Bombe:我们为什么要知道 MessageDigest 的内部状态?
@DanBarowy 好吧,您正在对其进行变异(即调用不返回值但导致其他方法返回不同值的方法),因此除非另有证明,否则您应该始终假设这样做不是线程安全的。
@Traubenfuchs MessageDigest 允许您分块输入数据。使用静态方法是不可能的。尽管您可以争辩说,当您可以一次传递所有数据时,为了方便起见,他们无论如何都应该添加一个。
C
CSchulz

如果您实际上希望将答案作为字符串而不是字节数组返回,您可以随时执行以下操作:

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,只是省略了尾随零,
次要 nitpick:调用 getInstance 后不需要 m.reset()。更轻微的:“你的文字在这里”需要双引号。
从 Java 11 开始,您可以使用 hashtext = "0".repeat(32 - hashtext.length()) + hashtext 而不是 while,因此编辑器不会警告您正在循环内进行字符串连接。
而不是 m.update(plaintext.getBytes());我建议指定编码。比如 m.update(plaintext.getBytes("UTF-8")); getBytes() 不保证编码,并且可能因系统而异,这可能导致同一字符串的系统之间的 MD5 结果不同。
l
lutzh

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


特别是,以字符串形式返回字节数据的“安全”编码表示的方法。
但是,如果不添加大量库或“手动”移植需要至少两个类的类,就没有简单的方法可以将 DigestUtils 类添加到您的项目中。
在maven repos中也找不到。呸呸呸。
应该在中央 Maven 存储库中,除非我快疯了: groupId=commons-codec artifactId=commons-codec version=1.5
d
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() 中使用的编码,否则您的代码将在不同的平台/用户设置上得到不同的结果。
@PaŭloEbermann 执行 MessageDigest.getInstance("MD5");不够?我试图在 getBytes() 中添加“MD5”,但它返回了错误
@BlazeTama“MD5”不是一种编码,它是一种消息摘要算法(而不是应该在新应用程序中使用的算法)。编码是将字节转换为字符串和将字符串转换为字节的算法对。例如“UTF-8”、“US-ASCII”、“ISO-8859-1”、“UTF-16BE”等。使用与计算此字符串的哈希的所有其他方相同的编码,否则您将得到不同的结果。
对于字符集的示例...(使用 UTF-8,这是我认为最好和最兼容的)... byte[] array = md.digest(md5.getBytes(Charset.forName("UTF-8")));
由于这不是我的解决方案,而且我自己也没有测试所有场景,所以我将保持不变,尽管我认为指定编码等可能是个好主意。
b
bluish

这是我的使用方法:

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 是:来自 Apache Commons projectorg.apache.commons.codec.binary.Hex


如果您仍然使用 Apache Commons Codec,您可以使用:commons.apache.org/codec/api-release/org/apache/commons/codec/…
我会用这个替换最后一行:String result = Hex.encodeHexString(resultByte);
r
rednoah

我发现这是最简洁明了的方法:

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

伟大的。它不会落入削减前导零的陷阱。
请注意,如果您使用的 API 级别 < 19,这不适用于 Android,但您只需使用 md5.update(string.getBytes("UTF-8")); 更改第二行这将添加另一个检查的异常来处理,虽然......
E
Eugene

我刚刚下载了 commons-codec.jar 并获得了完美的 php,例如 md5。这是manual

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

String Url = "your_url";

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

你有它。


这是提供与 MySQL 函数 md5(str) 相同的返回值的方法。许多其他答案确实返回了其他值。
这在 Android 上无法正常工作,因为 Android 捆绑了 commons-codec 1.2,您需要此解决方法:stackoverflow.com/a/9284092/2413303
非常适合 Gravatar 的电子邮件 MD5 哈希!谢谢
A
Anders R. Bystrup

找到了这个解决方案,它在从 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));
    }
}

代码是从 here 中提取的。


为什么这个答案是-1,而另一个较短且描述性较差的答案是+146?
很高兴使用 BigInteger 获得十六进制值 +1
我刚刚发现,在某些情况下,这只会生成 31 个字符长的 MD5 总和,而不是应有的 32 个字符
@kovica 这是因为,如果我没记错的话,起始零会被截断。String.format("%032x", new BigInteger(1, hash));这应该可以解决这个问题。 'hash' 是哈希的字节 []。
这似乎要优越得多。您甚至不必捕获尽可能多的异常。
s
stacker

另一个实现:

import javax.xml.bind.DatatypeConverter;

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

我见过的唯一一种不使用外部库的方法。
除非我弄错了,否则它总是以大写形式返回,这与不使用十六进制的 md5 不一致。甚至不确定它是否是真正的 md5
A
Arsen Khachaturyan

无需太复杂。
DigestUtils 工作正常,让您在使用 md5 哈希时感到舒适。

DigestUtils.md5Hex(_hash);

或者

DigestUtils.md5(_hash);

您可以使用任何其他加密方法,例如 shamd


a
andrewrjones

另一种选择是使用 Guava Hashing methods

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

如果您已经在使用 Guava(如果您没有使用,您可能应该使用 Guava)。


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

我有一个类(哈希)以哈希格式转换纯文本:md5或sha1,类似于php函数(md5sha1):

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


正如@CedricSimon 所说,这正是我想要的。在这里投票..谢谢!
m
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;
}

String.format("%1$032X", big) 具有大写格式
A
Austin Henley

Spring 中还有一个 DigestUtils 类:

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

此类包含完成这项工作的方法 md5DigestAsHex()


顺便说一句:这样做的性能比使用 BigInteger 创建十六进制字符串表示要好得多。
y
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();
}
}

f
frankodwyer

Bombe 的回答是正确的,但是请注意,除非您绝对必须使用 MD5(例如,为了互操作性而强制您使用),否则更好的选择是 SHA1,因为 MD5 存在长期使用的弱点。

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


您能否指出一些资源,我可以在其中了解每个资源的相对优缺点?
可能目前您能做的最好的事情就是使用 SHA1 并准备好在将来替换它。您可以使用更新的函数,但它们尚未经过大量研究。您可以跟踪在线安全资源以了解这种变化何时发生 - 例如 Bruce Schneier 的博客。
SHA1 是多余的,除非您想要一个加密安全的散列,即您不希望散列帮助重建原始消息,也不希望聪明的攻击者创建另一个与散列匹配的消息。如果原始文件不是秘密并且哈希值没有用于安全性,那么 MD5 既快速又简单。例如,Google Web Toolkit 在 JavaScript URL 中使用 MD5 哈希(例如 foo.js?hash=12345)。
L
Lukasz R.

另一种实现:Fast MD5 Implementation in Java

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

这是一个可靠的、独立的库,具有最少的依赖关系。好东西。
我发现它非常有用。一个 4.57GB 的文件需要 15357 毫秒,而 java 内置实现需要 19094 毫秒。
这非常有用。我遇到了 MessageDigest.getInstance("MD5") 的问题。
k
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)
        );
}

哦,顺便说一句,在除我自己以外的任何人都注意到我的 JRE 知识有多糟糕之前:我刚刚发现了 DigestInputStreamDigestOutputStream。我将编辑我的原始解决方案以反映我刚刚学到的内容。
G
Giancarlo Romeo
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();

G
Geordy James

与 PHP 不同,您可以通过调用 md5 函数(即 md5($text))对文本进行 MD5 散列,而在 Java 中它变得有点复杂。我通常通过调用一个返回 md5 哈希文本的函数来实现它。这是我实现它的方法,首先在您的主类中创建一个名为 md5hashing 的函数,如下所示。

public static String md5hashing(String text)
    {   String hashtext = null;
        try 
        {
            String plaintext = text;
            MessageDigest m = MessageDigest.getInstance("MD5");
            m.reset();
            m.update(plaintext.getBytes());
            byte[] digest = m.digest();
            BigInteger bigInt = new BigInteger(1,digest);
            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;   
            }
        } catch (Exception e1) 
        {
            // TODO: handle exception
            JOptionPane.showMessageDialog(null,e1.getClass().getName() + ": " + e1.getMessage());   
        }
        return hashtext;     
    }

现在在需要时调用该函数,如下所示。

String text = textFieldName.getText();
String pass = md5hashing(text);

在这里,您可以看到 hashtext 附加了一个零,以使其与 PHP 中的 md5 散列匹配。


M
Mihai Danila

对于它的价值,我偶然发现了这个,因为我想从一个将安装 COM 组件的程序的自然键合成 GUID;我想合成,以免管理 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();

实际上它不仅接受 MD5 字节数组(大小 == 16)。您可以传递任意长度的字节数组。它将通过 MD5 MessageDigest 转换为 MD5 字节数组(参见 nameUUIDFromBytes() source code
佚名

如果您不需要最好的安全性,MD5 非常好,如果您正在做检查文件完整性之类的事情,那么安全性就不是考虑因素。在这种情况下,您可能需要考虑更简单、更快的东西,例如 Adler32,它也受 Java 库支持。


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

这个给出了从 mysql 的 md5 函数或 php 的 md5 函数等获得的确切 md5。这是我使用的(你可以根据需要更改)

public static String md5( String input ) {
    try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(input.getBytes( "UTF-8" ));
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; i++) {
            sb.append( String.format( "%02x", array[i]));
        }
        return sb.toString();
    } catch ( NoSuchAlgorithmException | UnsupportedEncodingException e) {
        return null;            
    }

}

H
HimalayanCoder
import java.security.MessageDigest

val digest = MessageDigest.getInstance("MD5")

//Quick MD5 of text
val text = "MD5 this text!"
val md5hash1 = digest.digest(text.getBytes).map("%02x".format(_)).mkString

//MD5 of text with updates
digest.update("MD5 ".getBytes())
digest.update("this ".getBytes())
digest.update("text!".getBytes())
val md5hash2 = digest.digest().map(0xFF & _).map("%02x".format(_)).mkString

//Output
println(md5hash1 + " should be the same as " + md5hash2)

这是 Kotlin 语言吗?
@Isuru 看起来像 Scala
A
Ali

您可以通过使用 java.security 包中 MessageDigest 类中的方法来generate MD5 hash 给定文本。下面是完整的代码片段,

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;

public class MD5HashGenerator 
{

   public static void main(String args[]) throws NoSuchAlgorithmException
   {
       String stringToHash = "MyJavaCode"; 
       MessageDigest messageDigest = MessageDigest.getInstance("MD5");
       messageDigest.update(stringToHash.getBytes());
       byte[] digiest = messageDigest.digest();
       String hashedOutput = DatatypeConverter.printHexBinary(digiest);
       System.out.println(hashedOutput);
   }
}

MD5 函数的输出是由 32 个十六进制数字表示的 128 位哈希。

如果您使用的是 MySQL 之类的数据库,您也可以以更简单的方式执行此操作。查询 Select MD5(“text here”) 将返回括号中文本的 MD5 哈希值。


M
Marcelo Lopes

尝试这个:

public static String getHashMD5(String string) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        BigInteger bi = new BigInteger(1, md.digest(string.getBytes()));
        return bi.toString(16);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(MD5Utils.class
                .getName()).log(Level.SEVERE, null, ex);

        return "";
    }
}

这可能是最糟糕的解决方案,因为它会去除前导零。
P
Priyank Desai

这就是我来这里的目的——一个方便的 scala 函数,它返回 MD5 哈希字符串:

def md5(text: String) : String = java.security.MessageDigest.getInstance("MD5").digest(text.getBytes()).map(0xFF & _).map { "%02x".format(_) }.foldLeft(""){_ + _}

d
dcaswell
 import java.math.BigInteger;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;

/**
* MD5 encryption
*
* @author Hongten
*
*/
public class MD5 {

 public static void main(String[] args) {
     System.out.println(MD5.getMD5("123456"));
 }

 /**
  * Use md5 encoded code value
  *
  * @param sInput
  * clearly
  * @ return md5 encrypted password
  */
 public static String getMD5(String sInput) {

     String algorithm = "";
     if (sInput == null) {
         return "null";
     }
     try {
         algorithm = System.getProperty("MD5.algorithm", "MD5");
     } catch (SecurityException se) {
     }
     MessageDigest md = null;
     try {
         md = MessageDigest.getInstance(algorithm);
     } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
     }
     byte buffer[] = sInput.getBytes();

     for (int count = 0; count < sInput.length(); count++) {
         md.update(buffer, 0, count);
     }
     byte bDigest[] = md.digest();
     BigInteger bi = new BigInteger(bDigest);
     return (bi.toString(16));
 }
}

Codingkit 上有一篇关于此的文章。签出:http://codingkit.com/a/JAVA/2013/1020/2216.html


J
Janez Kuhar

您可以尝试使用 Caesar

第一个选项:

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