MD5算法是將數(shù)據(jù)進(jìn)行不可逆加密的算法有較好的安全性,在國內(nèi)如壽信的安全支付平臺(tái)就采用此算法。
源代碼如下
/**?*/
/**
**********************************************
MD5?算法的Java?Bean
Last?Modified:10,Mar,2001
************************************************
*/
import
?java.lang.reflect.
*
;


/**?*/
/**
***********************************************
md5?類實(shí)現(xiàn)了RSA?Data?Security,?Inc.在提交給IETF
的RFC1321中的MD5?message-digest?算法。
************************************************
*/
public
?
class
?MD5?
{

/**/
/*
?下面這些S11-S44實(shí)際上是一個(gè)4*4的矩陣,在原始的C實(shí)現(xiàn)中是用#define?實(shí)現(xiàn)的,
這里把它們實(shí)現(xiàn)成為static?final是表示了只讀,切能在同一個(gè)進(jìn)程空間內(nèi)的多個(gè)
Instance間共享
*/
static
?
final
?
int
?S11?
=
?
7
;
static
?
final
?
int
?S12?
=
?
12
;
static
?
final
?
int
?S13?
=
?
17
;
static
?
final
?
int
?S14?
=
?
22
;

static
?
final
?
int
?S21?
=
?
5
;
static
?
final
?
int
?S22?
=
?
9
;
static
?
final
?
int
?S23?
=
?
14
;
static
?
final
?
int
?S24?
=
?
20
;

static
?
final
?
int
?S31?
=
?
4
;
static
?
final
?
int
?S32?
=
?
11
;
static
?
final
?
int
?S33?
=
?
16
;
static
?
final
?
int
?S34?
=
?
23
;

static
?
final
?
int
?S41?
=
?
6
;
static
?
final
?
int
?S42?
=
?
10
;
static
?
final
?
int
?S43?
=
?
15
;
static
?
final
?
int
?S44?
=
?
21
;


static
?
final
?
byte
[]?PADDING?
=
?
{?
-
128
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
,?
0
?}
;

/**/
/*
?下面的三個(gè)成員是MD5計(jì)算過程中用到的3個(gè)核心數(shù)據(jù),在原始的C實(shí)現(xiàn)中
???被定義到MD5_CTX結(jié)構(gòu)中

*/
private
?
long
[]?state?
=
?
new
?
long
[
4
];??
//
?state?(ABCD)
private
?
long
[]?count?
=
?
new
?
long
[
2
];??
//
?number?of?bits,?modulo?2^64?(lsb?first)
private
?
byte
[]?buffer?
=
?
new
?
byte
[
64
];?
//
?input?buffer
/**/
/*
?digestHexStr是MD5的唯一一個(gè)公共成員,是最新一次計(jì)算結(jié)果的
?16進(jìn)制ASCII表示.
*/
public
?String?digestHexStr;


/**/
/*
?digest,是最新一次計(jì)算結(jié)果的2進(jìn)制內(nèi)部表示,表示128bit的MD5值.
*/
private
?
byte
[]?digest?
=
?
new
?
byte
[
16
];


/**/
/*
??getMD5ofStr是類MD5最主要的公共方法,入口參數(shù)是你想要進(jìn)行MD5變換的字符串
??返回的是變換完的結(jié)果,這個(gè)結(jié)果是從公共成員digestHexStr取得的.
*/
public
?String?getMD5ofStr(String?inbuf)?
{
md5Init();
md5update(inbuf.getBytes(),?inbuf.length());
md5Final();
digestHexStr?
=
?
""
;

for
?(
int
?i?
=
?
0
;?i?
<
?
16
;?i
++
)?
{
digestHexStr?
+=
?byteHEX(digest[i]);
}
return
?digestHexStr;

}
//
?這是MD5這個(gè)類的標(biāo)準(zhǔn)構(gòu)造函數(shù),JavaBean要求有一個(gè)public的并且沒有參數(shù)的構(gòu)造函數(shù)
public
?MD5()?
{
md5Init();

return
;
}
/**/
/*
?md5Init是一個(gè)初始化函數(shù),初始化核心變量,裝入標(biāo)準(zhǔn)的幻數(shù)?
*/
private
?
void
?md5Init()?
{
count[
0
]?
=
?
0L
;
count[
1
]?
=
?
0L
;
//
/*?Load?magic?initialization?constants.
state[
0
]?
=
?
0x67452301L
;
state[
1
]?
=
?
0xefcdab89L
;
state[
2
]?
=
?
0x98badcfeL
;
state[
3
]?
=
?
0x10325476L
;

return
;
}
/**/
/*
?F,?G,?H?,I?是4個(gè)基本的MD5函數(shù),在原始的MD5的C實(shí)現(xiàn)中,由于它們是
簡單的位運(yùn)算,可能出于效率的考慮把它們實(shí)現(xiàn)成了宏,在java中,我們把它們
實(shí)現(xiàn)成了private方法,名字保持了原來C中的。?
*/
private
?
long
?F(
long
?x,?
long
?y,?
long
?z)?
{
return
?(x?
&
?y)?
|
?((
~
x)?
&
?z);

}
private
?
long
?G(
long
?x,?
long
?y,?
long
?z)?
{
return
?(x?
&
?z)?
|
?(y?
&
?(
~
z));

}
private
?
long
?H(
long
?x,?
long
?y,?
long
?z)?
{
return
?x?
^
?y?
^
?z;
}
private
?
long
?I(
long
?x,?
long
?y,?
long
?z)?
{
return
?y?
^
?(x?
|
?(
~
z));
}
???
/**/
/*
?
??FF,GG,HH和II將調(diào)用F,G,H,I進(jìn)行近一步變換
??FF,?GG,?HH,?and?II?transformations?for?rounds?1,?2,?3,?and?4.
??Rotation?is?separate?from?addition?to?prevent?recomputation.
???
*/
??

private
?
long
?FF(
long
?a,?
long
?b,?
long
?c,?
long
?d,?
long
?x,?
long
?s,

long
?ac)?
{
a?
+=
?F?(b,?c,?d)?
+
?x?
+
?ac;
a?
=
?((
int
)?a?
<<
?s)?
|
?((
int
)?a?
>>>
?(
32
?
-
?s));
a?
+=
?b;
return
?a;
}
private
?
long
?GG(
long
?a,?
long
?b,?
long
?c,?
long
?d,?
long
?x,?
long
?s,

long
?ac)?
{
a?
+=
?G?(b,?c,?d)?
+
?x?
+
?ac;
a?
=
?((
int
)?a?
<<
?s)?
|
?((
int
)?a?
>>>
?(
32
?
-
?s));
a?
+=
?b;
return
?a;
}
private
?
long
?HH(
long
?a,?
long
?b,?
long
?c,?
long
?d,?
long
?x,?
long
?s,

long
?ac)?
{
a?
+=
?H?(b,?c,?d)?
+
?x?
+
?ac;
a?
=
?((
int
)?a?
<<
?s)?
|
?((
int
)?a?
>>>
?(
32
?
-
?s));
a?
+=
?b;
return
?a;
}
private
?
long
?II(
long
?a,?
long
?b,?
long
?c,?
long
?d,?
long
?x,?
long
?s,

long
?ac)?
{
a?
+=
?I?(b,?c,?d)?
+
?x?
+
?ac;
a?
=
?((
int
)?a?
<<
?s)?
|
?((
int
)?a?
>>>
?(
32
?
-
?s));
a?
+=
?b;
return
?a;
}
/**/
/*
md5update是MD5的主計(jì)算過程,inbuf是要變換的字節(jié)串,inputlen是長度,這個(gè)
函數(shù)由getMD5ofStr調(diào)用,調(diào)用之前需要調(diào)用md5init,因此把它設(shè)計(jì)成private的
*/
private
?
void
?md5update(
byte
[]?inbuf,?
int
?inputLen)?
{

int
?i,?index,?partLen;
byte
[]?block?
=
?
new
?
byte
[
64
];
index?
=
?(
int
)(count[
0
]?
>>>
?
3
)?
&
?
0x3F
;
//
?/*?update?number?of?bits?*/
if
?((count[
0
]?
+=
?(inputLen?
<<
?
3
))?
<
?(inputLen?
<<
?
3
))
count[
1
]
++
;
count[
1
]?
+=
?(inputLen?
>>>
?
29
);

partLen?
=
?
64
?
-
?index;

//
?Transform?as?many?times?as?possible.
if
?(inputLen?
>=
?partLen)?
{
md5Memcpy(buffer,?inbuf,?index,?
0
,?partLen);
md5Transform(buffer);


for
?(i?
=
?partLen;?i?
+
?
63
?
<
?inputLen;?i?
+=
?
64
)?
{

md5Memcpy(block,?inbuf,?
0
,?i,?
64
);
md5Transform?(block);
}
index?
=
?
0
;

}
?
else
i?
=
?
0
;

//
/*?Buffer?remaining?input?*/
md5Memcpy(buffer,?inbuf,?index,?i,?inputLen?
-
?i);

}
/**/
/*
??md5Final整理和填寫輸出結(jié)果
*/
private
?
void
?md5Final?()?
{
byte
[]?bits?
=
?
new
?
byte
[
8
];
int
?index,?padLen;

//
/*?Save?number?of?bits?*/
Encode?(bits,?count,?
8
);

//
/*?Pad?out?to?56?mod?64.
index?
=
?(
int
)(count[
0
]?
>>>
?
3
)?
&
?
0x3f
;
padLen?
=
?(index?
<
?
56
)?
?
?(
56
?
-
?index)?:?(
120
?
-
?index);
md5update?(PADDING,?padLen);

//
/*?Append?length?(before?padding)?*/
md5update(bits,?
8
);

//
/*?Store?state?in?digest?*/
Encode?(digest,?state,?
16
);

}
/**/
/*
?md5Memcpy是一個(gè)內(nèi)部使用的byte數(shù)組的塊拷貝函數(shù),從input的inpos開始把len長度的
?字節(jié)拷貝到output的outpos位置開始?
*/
private
?
void
?md5Memcpy?(
byte
[]?output,?
byte
[]?input,
int
?outpos,?
int
?inpos,?
int
?len)

{
int
?i;

for
?(i?
=
?
0
;?i?
<
?len;?i
++
)
output[outpos?
+
?i]?
=
?input[inpos?
+
?i];
}
/**/
/*
???md5Transform是MD5核心變換程序,有md5update調(diào)用,block是分塊的原始字節(jié)
*/
private
?
void
?md5Transform?(
byte
?block[])?
{
long
?a?
=
?state[
0
],?b?
=
?state[
1
],?c?
=
?state[
2
],?d?
=
?state[
3
];
long
[]?x?
=
?
new
?
long
[
16
];

Decode?(x,?block,?
64
);


/**/
/*
?Round?1?
*/
a?
=
?FF?(a,?b,?c,?d,?x[
0
],?S11,?
0xd76aa478L
);?
/**/
/*
?1?
*/
d?
=
?FF?(d,?a,?b,?c,?x[
1
],?S12,?
0xe8c7b756L
);?
/**/
/*
?2?
*/
c?
=
?FF?(c,?d,?a,?b,?x[
2
],?S13,?
0x242070dbL
);?
/**/
/*
?3?
*/
b?
=
?FF?(b,?c,?d,?a,?x[
3
],?S14,?
0xc1bdceeeL
);?
/**/
/*
?4?
*/
a?
=
?FF?(a,?b,?c,?d,?x[
4
],?S11,?
0xf57c0fafL
);?
/**/
/*
?5?
*/
d?
=
?FF?(d,?a,?b,?c,?x[
5
],?S12,?
0x4787c62aL
);?
/**/
/*
?6?
*/
c?
=
?FF?(c,?d,?a,?b,?x[
6
],?S13,?
0xa8304613L
);?
/**/
/*
?7?
*/
b?
=
?FF?(b,?c,?d,?a,?x[
7
],?S14,?
0xfd469501L
);?
/**/
/*
?8?
*/
a?
=
?FF?(a,?b,?c,?d,?x[
8
],?S11,?
0x698098d8L
);?
/**/
/*
?9?
*/
d?
=
?FF?(d,?a,?b,?c,?x[
9
],?S12,?
0x8b44f7afL
);?
/**/
/*
?10?
*/
c?
=
?FF?(c,?d,?a,?b,?x[
10
],?S13,?
0xffff5bb1L
);?
/**/
/*
?11?
*/
b?
=
?FF?(b,?c,?d,?a,?x[
11
],?S14,?
0x895cd7beL
);?
/**/
/*
?12?
*/
a?
=
?FF?(a,?b,?c,?d,?x[
12
],?S11,?
0x6b901122L
);?
/**/
/*
?13?
*/
d?
=
?FF?(d,?a,?b,?c,?x[
13
],?S12,?
0xfd987193L
);?
/**/
/*
?14?
*/
c?
=
?FF?(c,?d,?a,?b,?x[
14
],?S13,?
0xa679438eL
);?
/**/
/*
?15?
*/
b?
=
?FF?(b,?c,?d,?a,?x[
15
],?S14,?
0x49b40821L
);?
/**/
/*
?16?
*/
/**/
/*
?Round?2?
*/
a?
=
?GG?(a,?b,?c,?d,?x[
1
],?S21,?
0xf61e2562L
);?
/**/
/*
?17?
*/
d?
=
?GG?(d,?a,?b,?c,?x[
6
],?S22,?
0xc040b340L
);?
/**/
/*
?18?
*/
c?
=
?GG?(c,?d,?a,?b,?x[
11
],?S23,?
0x265e5a51L
);?
/**/
/*
?19?
*/
b?
=
?GG?(b,?c,?d,?a,?x[
0
],?S24,?
0xe9b6c7aaL
);?
/**/
/*
?20?
*/
a?
=
?GG?(a,?b,?c,?d,?x[
5
],?S21,?
0xd62f105dL
);?
/**/
/*
?21?
*/
d?
=
?GG?(d,?a,?b,?c,?x[
10
],?S22,?
0x2441453L
);?
/**/
/*
?22?
*/
c?
=
?GG?(c,?d,?a,?b,?x[
15
],?S23,?
0xd8a1e681L
);?
/**/
/*
?23?
*/
b?
=
?GG?(b,?c,?d,?a,?x[
4
],?S24,?
0xe7d3fbc8L
);?
/**/
/*
?24?
*/
a?
=
?GG?(a,?b,?c,?d,?x[
9
],?S21,?
0x21e1cde6L
);?
/**/
/*
?25?
*/
d?
=
?GG?(d,?a,?b,?c,?x[
14
],?S22,?
0xc33707d6L
);?
/**/
/*
?26?
*/
c?
=
?GG?(c,?d,?a,?b,?x[
3
],?S23,?
0xf4d50d87L
);?
/**/
/*
?27?
*/
b?
=
?GG?(b,?c,?d,?a,?x[
8
],?S24,?
0x455a14edL
);?
/**/
/*
?28?
*/
a?
=
?GG?(a,?b,?c,?d,?x[
13
],?S21,?
0xa9e3e905L
);?
/**/
/*
?29?
*/
d?
=
?GG?(d,?a,?b,?c,?x[
2
],?S22,?
0xfcefa3f8L
);?
/**/
/*
?30?
*/
c?
=
?GG?(c,?d,?a,?b,?x[
7
],?S23,?
0x676f02d9L
);?
/**/
/*
?31?
*/
b?
=
?GG?(b,?c,?d,?a,?x[
12
],?S24,?
0x8d2a4c8aL
);?
/**/
/*
?32?
*/
/**/
/*
?Round?3?
*/
a?
=
?HH?(a,?b,?c,?d,?x[
5
],?S31,?
0xfffa3942L
);?
/**/
/*
?33?
*/
d?
=
?HH?(d,?a,?b,?c,?x[
8
],?S32,?
0x8771f681L
);?
/**/
/*
?34?
*/
c?
=
?HH?(c,?d,?a,?b,?x[
11
],?S33,?
0x6d9d6122L
);?
/**/
/*
?35?
*/
b?
=
?HH?(b,?c,?d,?a,?x[
14
],?S34,?
0xfde5380cL
);?
/**/
/*
?36?
*/
a?
=
?HH?(a,?b,?c,?d,?x[
1
],?S31,?
0xa4beea44L
);?
/**/
/*
?37?
*/
d?
=
?HH?(d,?a,?b,?c,?x[
4
],?S32,?
0x4bdecfa9L
);?
/**/
/*
?38?
*/
c?
=
?HH?(c,?d,?a,?b,?x[
7
],?S33,?
0xf6bb4b60L
);?
/**/
/*
?39?
*/
b?
=
?HH?(b,?c,?d,?a,?x[
10
],?S34,?
0xbebfbc70L
);?
/**/
/*
?40?
*/
a?
=
?HH?(a,?b,?c,?d,?x[
13
],?S31,?
0x289b7ec6L
);?
/**/
/*
?41?
*/
d?
=
?HH?(d,?a,?b,?c,?x[
0
],?S32,?
0xeaa127faL
);?
/**/
/*
?42?
*/
c?
=
?HH?(c,?d,?a,?b,?x[
3
],?S33,?
0xd4ef3085L
);?
/**/
/*
?43?
*/
b?
=
?HH?(b,?c,?d,?a,?x[
6
],?S34,?
0x4881d05L
);?
/**/
/*
?44?
*/
a?
=
?HH?(a,?b,?c,?d,?x[
9
],?S31,?
0xd9d4d039L
);?
/**/
/*
?45?
*/
d?
=
?HH?(d,?a,?b,?c,?x[
12
],?S32,?
0xe6db99e5L
);?
/**/
/*
?46?
*/
c?
=
?HH?(c,?d,?a,?b,?x[
15
],?S33,?
0x1fa27cf8L
);?
/**/
/*
?47?
*/
b?
=
?HH?(b,?c,?d,?a,?x[
2
],?S34,?
0xc4ac5665L
);?
/**/
/*
?48?
*/
/**/
/*
?Round?4?
*/
a?
=
?II?(a,?b,?c,?d,?x[
0
],?S41,?
0xf4292244L
);?
/**/
/*
?49?
*/
d?
=
?II?(d,?a,?b,?c,?x[
7
],?S42,?
0x432aff97L
);?
/**/
/*
?50?
*/
c?
=
?II?(c,?d,?a,?b,?x[
14
],?S43,?
0xab9423a7L
);?
/**/
/*
?51?
*/
b?
=
?II?(b,?c,?d,?a,?x[
5
],?S44,?
0xfc93a039L
);?
/**/
/*
?52?
*/
a?
=
?II?(a,?b,?c,?d,?x[
12
],?S41,?
0x655b59c3L
);?
/**/
/*
?53?
*/
d?
=
?II?(d,?a,?b,?c,?x[
3
],?S42,?
0x8f0ccc92L
);?
/**/
/*
?54?
*/
c?
=
?II?(c,?d,?a,?b,?x[
10
],?S43,?
0xffeff47dL
);?
/**/
/*
?55?
*/
b?
=
?II?(b,?c,?d,?a,?x[
1
],?S44,?
0x85845dd1L
);?
/**/
/*
?56?
*/
a?
=
?II?(a,?b,?c,?d,?x[
8
],?S41,?
0x6fa87e4fL
);?
/**/
/*
?57?
*/
d?
=
?II?(d,?a,?b,?c,?x[
15
],?S42,?
0xfe2ce6e0L
);?
/**/
/*
?58?
*/
c?
=
?II?(c,?d,?a,?b,?x[
6
],?S43,?
0xa3014314L
);?
/**/
/*
?59?
*/
b?
=
?II?(b,?c,?d,?a,?x[
13
],?S44,?
0x4e0811a1L
);?
/**/
/*
?60?
*/
a?
=
?II?(a,?b,?c,?d,?x[
4
],?S41,?
0xf7537e82L
);?
/**/
/*
?61?
*/
d?
=
?II?(d,?a,?b,?c,?x[
11
],?S42,?
0xbd3af235L
);?
/**/
/*
?62?
*/
c?
=
?II?(c,?d,?a,?b,?x[
2
],?S43,?
0x2ad7d2bbL
);?
/**/
/*
?63?
*/
b?
=
?II?(b,?c,?d,?a,?x[
9
],?S44,?
0xeb86d391L
);?
/**/
/*
?64?
*/
state[
0
]?
+=
?a;
state[
1
]?
+=
?b;
state[
2
]?
+=
?c;
state[
3
]?
+=
?d;

}
/**/
/*
Encode把long數(shù)組按順序拆成byte數(shù)組,因?yàn)閖ava的long類型是64bit的,
??只拆低32bit,以適應(yīng)原始C實(shí)現(xiàn)的用途
*/
private
?
void
?Encode?(
byte
[]?output,?
long
[]?input,?
int
?len)?
{
int
?i,?j;


for
?(i?
=
?
0
,?j?
=
?
0
;?j?
<
?len;?i
++
,?j?
+=
?
4
)?
{
output[j]?
=
?(
byte
)(input[i]?
&
?
0xffL
);
output[j?
+
?
1
]?
=
?(
byte
)((input[i]?
>>>
?
8
)?
&
?
0xffL
);
output[j?
+
?
2
]?
=
?(
byte
)((input[i]?
>>>
?
16
)?
&
?
0xffL
);
output[j?
+
?
3
]?
=
?(
byte
)((input[i]?
>>>
?
24
)?
&
?
0xffL
);
}
}
/**/
/*
Decode把byte數(shù)組按順序合成成long數(shù)組,因?yàn)閖ava的long類型是64bit的,
??只合成低32bit,高32bit清零,以適應(yīng)原始C實(shí)現(xiàn)的用途
*/
private
?
void
?Decode?(
long
[]?output,?
byte
[]?input,?
int
?len)?
{
int
?i,?j;


for
?(i?
=
?
0
,?j?
=
?
0
;?j?
<
?len;?i
++
,?j?
+=
?
4
)
output[i]?
=
?b2iu(input[j])?
|
(b2iu(input[j?
+
?
1
])?
<<
?
8
)?
|
(b2iu(input[j?
+
?
2
])?
<<
?
16
)?
|
(b2iu(input[j?
+
?
3
])?
<<
?
24
);

return
;
}
???

/**/
/*
??b2iu是我寫的一個(gè)把byte按照不考慮正負(fù)號(hào)的原則的"升位"程序,因?yàn)閖ava沒有unsigned運(yùn)算
*/
public
?
static
?
long
?b2iu(
byte
?b)?
{
return
?b?
<
?
0
?
?
?b?
&
?
0x7F
?
+
?
128
?:?b;
}
/**/
/*
byteHEX(),用來把一個(gè)byte類型的數(shù)轉(zhuǎn)換成十六進(jìn)制的ASCII表示,
因?yàn)閖ava中的byte的toString無法實(shí)現(xiàn)這一點(diǎn),我們又沒有C語言中的
??sprintf(outbuf,"%02X",ib)
*/
public
?
static
?String?byteHEX(
byte
?ib)?
{

char
[]?Digit?
=
?
{?
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
A,B,C,D,E,F?}
;
char
?[]?ob?
=
?
new
?
char
[
2
];
ob[
0
]?
=
?Digit[(ib?
>>>
?
4
)?
&
?
0X0F
];
ob[
1
]?
=
?Digit[ib?
&
?
0X0F
];
String?s?
=
?
new
?String(ob);
return
?s;
}
}
?

posted?on?
2006
-
09
-
28
?
14
:
09
?圣域飛俠?閱讀(
1303
)?評(píng)論(
2
)??編輯?收藏?引用?
?

FeedBack:?
#?re:?java的md5加密類2006
-
09
-
29
?
08
:
41
?
|
?祥子


/**?*/
/**
?
*?Alipay.com?Inc.?Copyright?(c)?2004-2005?All?Rights?Reserved.?
*?
*?<p>?
*?Created?on?2005-7-9?
*?</p>?
*/
?

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


/**?*/
/**
?
*?MD5加密算法?
*/
?

public
?
class
?Md5Encrypt?
{?

/**?*/
/**
?
*?對(duì)字符串進(jìn)行MD5加密?
*?
*?
@param
?text?明文?
*?
*?
@return
?密文?
*/
?

public
?
static
?String?md5(String?text)?
{?
MessageDigest?msgDigest?
=
?
null
;?


try
?
{?
msgDigest?
=
?MessageDigest.getInstance(
"
MD5
"
);?

}
?
catch
?(NoSuchAlgorithmException?e)?
{?
throw
?
new
?IllegalStateException(
"
System?doesn't?support?MD5?algorithm.
"
);?
}
?

msgDigest.update(text.getBytes());?

byte
[]?bytes?
=
?msgDigest.digest();?

byte
?tb;?
char
?low;?
char
?high;?
char
?tmpChar;?

String?md5Str?
=
?
new
?String();?


for
?(
int
?i?
=
?
0
;?i?
<
?bytes.length;?i
++
)?
{?
tb?
=
?bytes[i];?

tmpChar?
=
?(
char
)?((tb?
>>>
?
4
)?
&
?
0x000f
);?


if
?(tmpChar?
>=
?
10
)?
{?
high?
=
?(
char
)?((
'
a
'
?
+
?tmpChar)?
-
?
10
);?

}
?
else
?
{?
high?
=
?(
char
)?(
'
0
'
?
+
?tmpChar);?
}
?

md5Str?
+=
?high;?
tmpChar?
=
?(
char
)?(tb?
&
?
0x000f
);?


if
?(tmpChar?
>=
?
10
)?
{?
low?
=
?(
char
)?((
'
a
'
?
+
?tmpChar)?
-
?
10
);?

}
?
else
?
{?
low?
=
?(
char
)?(
'
0
'
?
+
?tmpChar);?
}
?

md5Str?
+=
?low;?
}
?

return
?md5Str;?
}
?
}
?