RFC 1321中
定义的
MD5
是一种哈希算法,可将输入转换为哈希值的固定128位(16字节)长度。
注意
MD5不是抗冲突的–两个不同的输入可能会产生相同的哈希值。 阅读此
MD5漏洞
。 有许多快速安全的哈希算法,例如
SHA3-256
或
BLAKE2
; 对于密码哈希,我们可以使用
Bcrypt
或
Argon2
。 如果可能,请勿在任何与安全性有关的加密任务中使用MD5。
在Java中,我们可以使用
MessageDigest
生成
MD5
算法。
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] result = md.digest(input);
1. Java MD5哈希
此Java示例使用
MD5
从字符串生成哈希值。
MD5Utils.java
package com.mkyong.crypto.hash;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
private static final Charset UTF_8 = StandardCharsets.UTF_8;
private static final String OUTPUT_FORMAT = "%-20s:%s";
private static byte[] digest(byte[] input) {
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException(e);
byte[] result = md.digest(input);
return result;
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
return sb.toString();
public static void main(String[] args) {
String pText = "Hello MD5";
System.out.println(String.format(OUTPUT_FORMAT, "Input (string)", pText));
System.out.println(String.format(OUTPUT_FORMAT, "Input (length)", pText.length()));
byte[] md5InBytes = MD5Utils.digest(pText.getBytes(UTF_8));
System.out.println(String.format(OUTPUT_FORMAT, "MD5 (hex) ", bytesToHex(md5InBytes)));
// fixed length, 16 bytes, 128 bits.
System.out.println(String.format(OUTPUT_FORMAT, "MD5 (length)", md5InBytes.length));
Terminal
Input (string) :Hello MD5
Input (length) :9
MD5 (hex) :e5dadf6524624f79c3127e247f04b548
MD5 (length) :16
尝试另一个String,例如Hello MD5 Hello MD5
。 输入长度有所不同,但是MD5哈希值的输出仍然是128位16字节。
Terminal
Input (string) :Hello MD5 Hello MD5
Input (length) :19
MD5 (hex) :6219b1bc3542949e012616059409f1cc
MD5 (length) :16
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
private static final Charset UTF_8 = StandardCharsets.UTF_8;
private static final String OUTPUT_FORMAT = "%-20s:%s";
private static byte[] checksum(String filePath) {
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException(e);
try (InputStream is = new FileInputStream(filePath);
DigestInputStream dis = new DigestInputStream(is, md)) {
while (dis.read() != -1) ; //empty loop to clear the data
md = dis.getMessageDigest();
} catch (IOException e) {
throw new IllegalArgumentException(e);
return md.digest();
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
return sb.toString();
public static void main(String[] args) {
String file = "c:\\test\\readme.txt";
System.out.println(String.format(OUTPUT_FORMAT, "Input (file) ", file));
System.out.println(String.format(OUTPUT_FORMAT, "MD5 (checksum hex) ", bytesToHex(checksum(file))));
Terminal
Input (file) :c:\test\readme.txt
MD5 (checksum hex) :e5dadf6524624f79c3127e247f04b548
3. Apache Commons编解码器
本示例使用commons-codec
库生成MD5哈希值。
pom.xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
3.1来自字符串的MD5哈希值。
import org.apache.commons.codec.digest.DigestUtils;
String pText = "Hello MD5";
System.out.println(DigestUtils.md5Hex(password));
Terminal
e5dadf6524624f79c3127e247f04b548
3.2文件中的MD5哈希值。
try (InputStream is = new FileInputStream("c:\\test\\readme.txt")) {
String checksum = DigestUtils.md5Hex(is);
System.out.println(checksum);
} catch (IOException e) {
e.printStackTrace();
Terminal
e5dadf6524624f79c3127e247f04b548
下载源代码
$ git clone https://github.com/mkyong/core-java
$ cd java-crypto
标签: 加密 哈希 Java md5
RFC 1321中定义的MD5是一种哈希算法,可将输入转换为哈希值的固定128位(16字节)长度。 注意 MD5不是抗冲突的–两个不同的输入可能会产生相同的哈希值。 阅读此MD5漏洞 。 有许多快速安全的哈希算法,例如SHA3-256或BLAKE2 ; 对于密码哈希,我们可以使用Bcrypt或Argon2 。 如果可能,请勿在任何与安全性有关的加密任务中使用MD5。 在Java中,...
对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。
在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448。因此,信息的位长(Bits Length)将被扩展至N*512+448,N为一个非负整数,N可以是零。填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。然后,在这个结果后面附加一个以64位二进制表示的填充前信息长度。经过这两步的处理,现在的信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。这样做的原因是为满足后面处理中对信息长度的要求。
MD5中有四个32位被称作链接变量(Chaining Variable)的整数参数,他们分别为:A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476。
当设置好这四个链接变量后,就开始进入算法的四轮循环运算。循环的次数是信息中512位信息分组的数目。
将上面四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。
主循环有四轮(MD4只有三轮),每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。
以一下是每次操作中用到的四个非线性函数(每轮一个)。
F(X,Y,Z) =(X&Y)|((~X)&Z)
G(X,Y,Z) =(X&Z)|(Y&(~Z))
H(X,Y,Z) =X^Y^Z
I(X,Y,Z)=Y^(X|(~Z))
(&是与,|是或,~是非,^是异或)
这四个函数的说明:如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。
F是一个逐位运算的函数。即,如果X,那么Y,否则Z。函数H是逐位奇偶操作符。
假设Mj表示消息的第j个子分组(从0到15), 常数ti是4294967296*abs(sin(i))的整数部分,i取值从1到64,单位是弧度。(4294967296等于2的32次方)
FF(a, b, c, d, Mj, s, ti)表示 a = b + ((a + F(b, c, d) + Mj + ti) << s)
GG(a, b, c, d, Mj, s, ti)表示 a = b + ((a + G(b, c, d) + Mj + ti) << s)
HH(a, b, c, d, Mj, s, ti)表示 a = b + ((a + H(b, c, d) + Mj + ti) << s)
II(a, b, c, d, Mj, s, ti)表示 a = b + ((a + I(b, c, d) + Mj + ti) << s)
这四轮(64步)是:
FF(a, b, c, d, M0, 7, 0xd76aa478)
FF(d, a, b, c, M1, 12, 0xe8c7b756)
FF(c, d, a, b, M2, 17, 0x242070db)
FF(b, c, d, a, M3, 22, 0xc1bdceee)
FF(a, b, c, d, M4, 7, 0xf57c0faf)
FF(d, a, b, c, M5, 12, 0x4787c62a)
FF(c, d, a, b, M6, 17, 0xa8304613)
FF(b, c, d, a, M7, 22, 0xfd469501)
FF(a, b, c, d, M8, 7, 0x698098d8)
FF(d, a, b, c, M9, 12, 0x8b44f7af)
FF(c, d, a, b, M10, 17, 0xffff5bb1)
FF(b, c, d, a, M11, 22, 0x895cd7be)
FF(a, b, c, d, M12, 7, 0x6b901122)
FF(d, a, b, c, M13, 12, 0xfd987193)
FF(c, d, a, b, M14, 17, 0xa679438e)
FF(b, c, d, a, M15, 22, 0x49b40821)
GG(a, b, c, d, M1, 5, 0xf61e2562)
GG(d, a, b, c, M6, 9, 0xc040b340)
GG(c, d, a, b, M11, 14, 0x265e5a51)
GG(b, c, d, a, M0, 20, 0xe9b6c7aa)
GG(a, b, c, d, M5, 5, 0xd62f105d)
GG(d, a, b, c, M10, 9, 0x02441453)
GG(c, d, a, b, M15, 14, 0xd8a1e681)
GG(b, c, d, a, M4, 20, 0xe7d3fbc8)
GG(a, b, c, d, M9, 5, 0x21e1cde6)
GG(d, a, b, c, M14, 9, 0xc33707d6)
GG(c, d, a, b, M3, 14, 0xf4d50d87)
GG(b, c, d, a, M8, 20, 0x455a14ed)
GG(a, b, c, d, M13, 5, 0xa9e3e905)
GG(d, a, b, c, M2, 9, 0xfcefa3f8)
GG(c, d, a, b, M7, 14, 0x676f02d9)
GG(b, c, d, a, M12, 20, 0x8d2a4c8a)
HH(a, b, c, d, M5, 4, 0xfffa3942)
HH(d, a, b, c, M8, 11, 0x8771f681)
HH(c, d, a, b, M11, 16, 0x6d9d6122)
HH(b, c, d, a, M14, 23, 0xfde5380c)
HH(a, b, c, d, M1, 4, 0xa4beea44)
HH(d, a, b, c, M4, 11, 0x4bdecfa9)
HH(c, d, a, b, M7, 16, 0xf6bb4b60)
HH(b, c, d, a, M10, 23, 0xbebfbc70)
HH(a, b, c, d, M13, 4, 0x289b7ec6)
HH(d, a, b, c, M0, 11, 0xeaa127fa)
HH(c, d, a, b, M3, 16, 0xd4ef3085)
HH(b, c, d, a, M6, 23, 0x04881d05)
HH(a, b, c, d, M9, 4, 0xd9d4d039)
HH(d, a, b, c, M12, 11, 0xe6db99e5)
HH(c, d, a, b, M15, 16, 0x1fa27cf8)
HH(b, c, d, a, M2, 23, 0xc4ac5665)
II(a, b, c, d, M0, 6, 0xf4292244)
II(d, a, b, c, M7, 10, 0x432aff97)
II(c, d, a, b, M14, 15, 0xab9423a7)
II(b, c, d, a, M5, 21, 0xfc93a039)
II(a, b, c, d, M12, 6, 0x655b59c3)
II(d, a, b, c, M3, 10, 0x8f0ccc92)
II(c, d, a, b, M10, 15, 0xffeff47d)
II(b, c, d, a, M1, 21, 0x85845dd1)
II(a, b, c, d, M8, 6, 0x6fa87e4f)
II(d, a, b, c, M15, 10, 0xfe2ce6e0)
II(c, d, a, b, M6, 15, 0xa3014314)
II(b, c, d, a, M13, 21, 0x4e0811a1)
II(a, b, c, d, M4, 6, 0xf7537e82)
II(d, a, b, c, M11, 10, 0xbd3af235)
II(c, d, a, b, M2, 15, 0x2ad7d2bb)
II(b, c, d, a, M9, 21, 0xeb86d391)
所有这些完成之后,将A、B、C、D分别加上a、b、c、d。然后用下一分组数据继续运行算法,最后的输出是A、B、C和D的级联。
当你按照我上面所说的方法实现MD5算法以后,你可以用以下几个信息对你做出来的程序作一个简单的测试,看看程序有没有错误。
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") =
f29939a25efabaef3b87e2cbfe641315
VB2010实现
Imports System
Imports System.Security.Cryptography
Imports System.Text
Module Example
' 哈希输入字符串并返回一个32字符的十六进制字符串哈希。
Function getMd5Hash(ByVal input As String) As String
' 创建新的一个MD5CryptoServiceProvider对象的实例。
Dim md5Hasher As New MD5CryptoServiceProvider()
' 输入的字符串转换为字节数组,并计算哈希。
Dim data As Byte() = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input))
' 创建一个新的StringBuilder收集的字节,并创建一个字符串。
Dim sBuilder As New StringBuilder()
' 通过每个字节的哈希数据和格式为十六进制字符串的每一个循环。
Dim i As Integer
For i = 0 To data.Length - 1
sBuilder.Append(data(i).ToString("x2"))
Next i
' 返回十六进制字符串。
Return sBuilder.ToString()
End Function
' 验证对一个字符串的哈希值。
Function verifyMd5Hash(ByVal input As String, ByVal hash As String) As Boolean
' 哈希的输入。
Dim hashOfInput As String = getMd5Hash(input)
' 创建StringComparer1的哈希进行比较。
Dim comparer As StringComparer = StringComparer.OrdinalIgnoreCase
If 0 = comparer.Compare(hashOfInput, hash) Then
Return True
Return False
End If
End Function
Sub Main()
Dim source As String = "Hello World!"
Dim hash As String = getMd5Hash(source)
Console.WriteLine("进行MD5加密的字符串为:" + source + " 加密的结果是:" + hash + ".")
Console.WriteLine("验证哈希...")
If verifyMd5Hash(source, hash) Then
Console.WriteLine("哈希值是相同的。")
Console.WriteLine("哈希值是不相同的。")
End If
End Sub
End Module
' 此代码示例产生下面的输出:
' 进行MD5加密的字符串为:Hello World! 加密的结果是:ed076287532e86365e841e92bfc50d8c.
' 验证哈希...
' 哈希值是相同的。
伪代码实现
//Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating
var int[64] r, k //r specifies the per-round shift amounts
r[ 0..15]:= {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22}
r[16..31]:= {5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20}
r[32..47]:= {4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23}
r[48..63]:= {6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}
//Use binary integer part of the sines of integers as constants:
for i from 0 to 63
k[i] := floor(abs(sin(i + 1)) × 2^32)
//Initialize variables:
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h2 := 0x98BADCFE
var int h3 := 0x10325476
//Pre-processing:
append "1" bit to message
append "0" bits until message length in bits ≡ 448 (mod 512)
append bit length of message as 64-bit little-endian integer to message
//Process the message in successive 512-bit chunks:
for each 512-bit chunk of message
break chunk into sixteen 32-bit little-endian words w[i], 0 ≤ i ≤ 15
//Initialize hash value for this chunk:
var int a := h0
var int b := h1
var int c := h2
var int d := h3
//Main loop:
for i from 0 to 63
if 0 ≤ i ≤ 15 then
f := (b and c) or ((not b) and d)
g := i
else if 16 ≤ i ≤ 31
f := (d and b) or ((not d) and c)
g := (5×i + 1) mod 16
else if 32 ≤ i ≤ 47
f := b xor c xor d
g := (3×i + 5) mod 16
else if 48 ≤ i ≤ 63
f := c xor (b or (not d))
g := (7×i) mod 16
temp := d
d := c
c := b
b := ((a + f + k[i] + w[g]) leftrotate r[i]) + b
a := temp
//Add this chunk's hash to result so far:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
var int digest := h0 append h1 append h2 append h3
//(expressed as little-endian)
标准C语言实现
具体的一个MD5实现
* md5 -- compute and check MD5 message digest.
* this version only can calculate the char string.
* MD5 (Message-Digest algorithm 5) is a widely used, partially
* insecure cryptographic hash function with a 128-bit hash value.
* Author: redraiment
* Date: Aug 27, 2008
* Version: 0.1.6
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#define SINGLE_ONE_BIT 0x80
#define BLOCK_SIZE 512
#define MOD_SIZE 448
#define APP_SIZE 64
#define BITS 8
// MD5 Chaining Variable
#define A 0x67452301UL
#define B 0xEFCDAB89UL
#define C 0x98BADCFEUL
#define D 0x10325476UL
// Creating own types
#ifdef UINT64
# undef UINT64
#endif
#ifdef UINT32
# undef UINT32
#endif
typedef unsigned long long UINT64;
typedef unsigned long UINT32;
typedef unsigned char UINT8;
typedef struct
char * message;
UINT64 length;
}STRING;
const UINT32 X[4][2] = {{0, 1}, {1, 5}, {5, 3}, {0, 7}};
// Constants for MD5 transform routine.
const UINT32 S[4][4] = {
{ 7, 12, 17, 22 },
{ 5, 9, 14, 20 },
{ 4, 11, 16, 23 },
{ 6, 10, 15, 21 }
// F, G, H and I are basic MD5 functions.
UINT32 F( UINT32 X, UINT32 Y, UINT32 Z )
return ( X & Y ) | ( ~X & Z );
UINT32 G( UINT32 X, UINT32 Y, UINT32 Z )
return ( X & Z ) | ( Y & ~Z );
UINT32 H( UINT32 X, UINT32 Y, UINT32 Z )
return X ^ Y ^ Z;
UINT32 I( UINT32 X, UINT32 Y, UINT32 Z )
return Y ^ ( X | ~Z );
// rotates x left s bits.
UINT32 rotate_left( UINT32 x, UINT32 s )
return ( x << s ) | ( x >> ( 32 - s ) );
// Pre-processin
UINT32 count_padding_bits ( UINT32 length )
UINT32 div = length * BITS / BLOCK_SIZE;
UINT32 mod = length * BITS % BLOCK_SIZE;
UINT32 c_bits;
if ( mod == 0 )
c_bits = MOD_SIZE;
c_bits = ( MOD_SIZE + BLOCK_SIZE - mod ) % BLOCK_SIZE;
return c_bits / BITS;
STRING append_padding_bits ( char * argv )
UINT32 msg_length = strlen ( argv );
UINT32 bit_length = count_padding_bits ( msg_length );
UINT64 app_length = msg_length * BITS;
STRING string;
string.message = (char *)malloc(msg_length + bit_length + APP_SIZE / BITS);
// Save message
strncpy ( string.message, argv, msg_length );
// Pad out to mod 64.
memset ( string.message + msg_length, 0, bit_length );
string.message [ msg_length ] = SINGLE_ONE_BIT;
// Append length (before padding).
memmove ( string.message + msg_length + bit_length, (char *)&app;_length, sizeof( UINT64 ) );
string.length = msg_length + bit_length + sizeof( UINT64 );
return string;
int main ( int argc, char *argv[] )
STRING string;
UINT32 w[16];
UINT32 chain[4];
UINT32 state[4];
UINT8 r[16];
UINT32 ( *auxi[ 4 ])( UINT32, UINT32, UINT32 ) = { F, G, H, I };
int roundIdx;
int argIdx;
int sIdx;
int wIdx;
int i;
int j;
if ( argc < 2 )
fprintf ( stderr, "usage: %s string ...\n", argv[ 0 ] );
return EXIT_FAILURE;
for ( argIdx = 1; argIdx < argc; argIdx++ )
string = append_padding_bits ( argv[ argIdx ] );
// MD5 initialization.
chain[0] = A;
chain[1] = B;
chain[2] = C;
chain[3] = D;
for ( j = 0; j < string.length; j += BLOCK_SIZE / BITS)
memmove ( (char *)w, string.message + j, BLOCK_SIZE / BITS );
memmove ( state, chain, sizeof(chain) );
for ( roundIdx = 0; roundIdx < 4; roundIdx++ )
wIdx = X[ roundIdx ][ 0 ];
sIdx = 0;
for ( i = 0; i < 16; i++ )
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
state[sIdx] = state [ (sIdx + 1) % 4 ] +
rotate_left ( state[sIdx] +
( *auxi[ roundIdx ] )
( state[(sIdx+1) % 4], state[(sIdx+2) % 4], state[(sIdx+3) % 4]) +
w[ wIdx ] +
(UINT32)floor( (1UL << 32) * fabs(sin( roundIdx * 16 + i + 1 )) ),
S[ roundIdx ][ i % 4 ]);
sIdx = ( sIdx + 3 ) % 4;
wIdx = ( wIdx + X[ roundIdx ][ 1 ] ) & 0xF;
chain[ 0 ] += state[ 0 ];
chain[ 1 ] += state[ 1 ];
chain[ 2 ] += state[ 2 ];
chain[ 3 ] += state[ 3 ];
memmove ( r + 0, (char *)&chain;[0], sizeof(UINT32) );
memmove ( r + 4, (char *)&chain;[1], sizeof(UINT32) );
memmove ( r + 8, (char *)&chain;[2], sizeof(UINT32) );
memmove ( r + 12, (char *)&chain;[3], sizeof(UINT32) );
for ( i = 0; i < 16; i++ )
printf ( "x", r[i] );
putchar ( '\n' );
free(string.message);
return EXIT_SUCCESS;
/* 以上程序可以在任意一款支持ANSI C的编译器上编译通过 */
/* 直接复制粘贴,请删除多余的空格,并调整格式,否则可能有编译错误 */
/* 在linux下编译,要添加链接库,命令如:gcc -o md5 md5.c -lm */
因为加密要对应解密,而MD5是不可逆的,所以,严格来说,MD5不是加密算法,而是一种hash算法,准确的应该叫信息摘要算法。
Hash算法特别的地方在于它是一种单向算法,用户可以通过Hash算法对目标信息生成一段特定长度的唯一的Hash值,却不能通过这个Hash值重新获得目标信息。因此Hash算法常用在不可还原的密码存储、信息完整性校验等。
下文中将进行MD5加...
RFC 1321中定义的MD5是一种哈希算法,可将输入转换为哈希值的固定128位(16字节)长度。
注意 MD5不是抗冲突的–两个不同的输入可能会产生相同的哈希值。 阅读此MD5漏洞 。
在Python中,我们可以使用hashlib.md5()从字符串生成MD5哈希值。
1. Python MD5哈希
import hashlib
result = hashlib.md5(b...
Java中有很多可用的MD5工具包,用于计算或验证MD5哈希值。这些工具包提供了一系列方法和函数,用于将字符串或文件转换为MD5哈希值。
其中最常用的MD5工具包是Java标准库中的java.security包下的MessageDigest类。通过以下步骤可以使用Java提供的工具包进行MD5计算:
1. 首先,创建一个MessageDigest对象,通过`getInstance("MD5")`方法指定使用MD5算法。
2. 然后,可以通过调用`update(byte[] input)`方法,将待计算的数据以字节数组的形式传递给MessageDigest对象。
3. 最后,通过调用`digest()`方法计算MD5哈希值。
以下是一个简单的示例代码,展示如何使用Java的MD5工具包计算字符串的MD5哈希值:
```java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Example {
public static void main(String[] args) {
String input = "Hello, world!";
try {
// 创建MessageDigest对象
MessageDigest md = MessageDigest.getInstance("MD5");
// 将字符串转换为字节数组,并计算MD5哈希值
byte[] mdBytes = md.digest(input.getBytes());
// 将字节数组转换为十六进制字符串表示
StringBuilder sb = new StringBuilder();
for (byte b : mdBytes) {
sb.append(String.format("%02x", b));
// 输出MD5哈希值
System.out.println("MD5: " + sb.toString());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
除了Java标准库中的MessageDigest类,还有一些第三方库,如Apache Commons Codec等,也提供了更方便的MD5哈希值计算工具包。使用这些工具包可以简化MD5的计算过程,并提供更多的功能和选项供开发者使用。
总之,Java提供了多种MD5工具包,可以方便地计算和验证MD5哈希值。根据实际需求,选择合适的工具包,可以更高效地进行MD5相关的操作。