duansky'weblog

统计

留言簿(3)

友情链接

阅读排行榜

评论排行榜

java的md5加密类

MD5算法是将数据进行不可逆加密的算法有较好的安全性,在国内如寿信的安全支付平台就采用此算法。
源代码如下

/** **********************************************
MD5 算法的Java Bean
Last Modified:10,Mar,2001
************************************************
*/


import  java.lang.reflect. * ;

/** ***********************************************
md5 类实现了RSA Data Security, Inc.在提交给IETF
的RFC1321中的MD5 message-digest 算法。
************************************************
*/


public   class  MD5  {
/*  下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的,
这里把它们实现成为static final是表示了只读,切能在同一个进程空间内的多个
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  }
;
/*  下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中
   被定义到MD5_CTX结构中

*/

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的唯一一个公共成员,是最新一次计算结果的
  16进制ASCII表示.
*/

public  String digestHexStr;

/*  digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值.
*/

private   byte [] digest  =   new   byte [ 16 ];

/*
  getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串
  返回的是变换完的结果,这个结果是从公共成员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这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数
public  MD5()  {
md5Init();

return ;
}




/*  md5Init是一个初始化函数,初始化核心变量,装入标准的幻数  */
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个基本的MD5函数,在原始的MD5的C实现中,由于它们是
简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们
  实现成了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将调用F,G,H,I进行近一步变换
  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)  {
+=  F (b, c, d)  +  x  +  ac;
=  (( int ) a  <<  s)  |  (( int ) a  >>>  ( 32   -  s));
+=  b;
return  a;
}


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

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

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

/*
md5update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个
函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成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

=   0 ;

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

}


/*
  md5Final整理和填写输出结果
*/

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是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的
      字节拷贝到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调用,block是分块的原始字节
*/

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  */
=  FF (a, b, c, d, x[ 0 ], S11,  0xd76aa478L );  /*  1  */
=  FF (d, a, b, c, x[ 1 ], S12,  0xe8c7b756L );  /*  2  */
=  FF (c, d, a, b, x[ 2 ], S13,  0x242070dbL );  /*  3  */
=  FF (b, c, d, a, x[ 3 ], S14,  0xc1bdceeeL );  /*  4  */
=  FF (a, b, c, d, x[ 4 ], S11,  0xf57c0fafL );  /*  5  */
=  FF (d, a, b, c, x[ 5 ], S12,  0x4787c62aL );  /*  6  */
=  FF (c, d, a, b, x[ 6 ], S13,  0xa8304613L );  /*  7  */
=  FF (b, c, d, a, x[ 7 ], S14,  0xfd469501L );  /*  8  */
=  FF (a, b, c, d, x[ 8 ], S11,  0x698098d8L );  /*  9  */
=  FF (d, a, b, c, x[ 9 ], S12,  0x8b44f7afL );  /*  10  */
=  FF (c, d, a, b, x[ 10 ], S13,  0xffff5bb1L );  /*  11  */
=  FF (b, c, d, a, x[ 11 ], S14,  0x895cd7beL );  /*  12  */
=  FF (a, b, c, d, x[ 12 ], S11,  0x6b901122L );  /*  13  */
=  FF (d, a, b, c, x[ 13 ], S12,  0xfd987193L );  /*  14  */
=  FF (c, d, a, b, x[ 14 ], S13,  0xa679438eL );  /*  15  */
=  FF (b, c, d, a, x[ 15 ], S14,  0x49b40821L );  /*  16  */

/*  Round 2  */
=  GG (a, b, c, d, x[ 1 ], S21,  0xf61e2562L );  /*  17  */
=  GG (d, a, b, c, x[ 6 ], S22,  0xc040b340L );  /*  18  */
=  GG (c, d, a, b, x[ 11 ], S23,  0x265e5a51L );  /*  19  */
=  GG (b, c, d, a, x[ 0 ], S24,  0xe9b6c7aaL );  /*  20  */
=  GG (a, b, c, d, x[ 5 ], S21,  0xd62f105dL );  /*  21  */
=  GG (d, a, b, c, x[ 10 ], S22,  0x2441453L );  /*  22  */
=  GG (c, d, a, b, x[ 15 ], S23,  0xd8a1e681L );  /*  23  */
=  GG (b, c, d, a, x[ 4 ], S24,  0xe7d3fbc8L );  /*  24  */
=  GG (a, b, c, d, x[ 9 ], S21,  0x21e1cde6L );  /*  25  */
=  GG (d, a, b, c, x[ 14 ], S22,  0xc33707d6L );  /*  26  */
=  GG (c, d, a, b, x[ 3 ], S23,  0xf4d50d87L );  /*  27  */
=  GG (b, c, d, a, x[ 8 ], S24,  0x455a14edL );  /*  28  */
=  GG (a, b, c, d, x[ 13 ], S21,  0xa9e3e905L );  /*  29  */
=  GG (d, a, b, c, x[ 2 ], S22,  0xfcefa3f8L );  /*  30  */
=  GG (c, d, a, b, x[ 7 ], S23,  0x676f02d9L );  /*  31  */
=  GG (b, c, d, a, x[ 12 ], S24,  0x8d2a4c8aL );  /*  32  */

/*  Round 3  */
=  HH (a, b, c, d, x[ 5 ], S31,  0xfffa3942L );  /*  33  */
=  HH (d, a, b, c, x[ 8 ], S32,  0x8771f681L );  /*  34  */
=  HH (c, d, a, b, x[ 11 ], S33,  0x6d9d6122L );  /*  35  */
=  HH (b, c, d, a, x[ 14 ], S34,  0xfde5380cL );  /*  36  */
=  HH (a, b, c, d, x[ 1 ], S31,  0xa4beea44L );  /*  37  */
=  HH (d, a, b, c, x[ 4 ], S32,  0x4bdecfa9L );  /*  38  */
=  HH (c, d, a, b, x[ 7 ], S33,  0xf6bb4b60L );  /*  39  */
=  HH (b, c, d, a, x[ 10 ], S34,  0xbebfbc70L );  /*  40  */
=  HH (a, b, c, d, x[ 13 ], S31,  0x289b7ec6L );  /*  41  */
=  HH (d, a, b, c, x[ 0 ], S32,  0xeaa127faL );  /*  42  */
=  HH (c, d, a, b, x[ 3 ], S33,  0xd4ef3085L );  /*  43  */
=  HH (b, c, d, a, x[ 6 ], S34,  0x4881d05L );  /*  44  */
=  HH (a, b, c, d, x[ 9 ], S31,  0xd9d4d039L );  /*  45  */
=  HH (d, a, b, c, x[ 12 ], S32,  0xe6db99e5L );  /*  46  */
=  HH (c, d, a, b, x[ 15 ], S33,  0x1fa27cf8L );  /*  47  */
=  HH (b, c, d, a, x[ 2 ], S34,  0xc4ac5665L );  /*  48  */

/*  Round 4  */
=  II (a, b, c, d, x[ 0 ], S41,  0xf4292244L );  /*  49  */
=  II (d, a, b, c, x[ 7 ], S42,  0x432aff97L );  /*  50  */
=  II (c, d, a, b, x[ 14 ], S43,  0xab9423a7L );  /*  51  */
=  II (b, c, d, a, x[ 5 ], S44,  0xfc93a039L );  /*  52  */
=  II (a, b, c, d, x[ 12 ], S41,  0x655b59c3L );  /*  53  */
=  II (d, a, b, c, x[ 3 ], S42,  0x8f0ccc92L );  /*  54  */
=  II (c, d, a, b, x[ 10 ], S43,  0xffeff47dL );  /*  55  */
=  II (b, c, d, a, x[ 1 ], S44,  0x85845dd1L );  /*  56  */
=  II (a, b, c, d, x[ 8 ], S41,  0x6fa87e4fL );  /*  57  */
=  II (d, a, b, c, x[ 15 ], S42,  0xfe2ce6e0L );  /*  58  */
=  II (c, d, a, b, x[ 6 ], S43,  0xa3014314L );  /*  59  */
=  II (b, c, d, a, x[ 13 ], S44,  0x4e0811a1L );  /*  60  */
=  II (a, b, c, d, x[ 4 ], S41,  0xf7537e82L );  /*  61  */
=  II (d, a, b, c, x[ 11 ], S42,  0xbd3af235L );  /*  62  */
=  II (c, d, a, b, x[ 2 ], S43,  0x2ad7d2bbL );  /*  63  */
=  II (b, c, d, a, x[ 9 ], S44,  0xeb86d391L );  /*  64  */

state[
0 +=  a;
state[
1 +=  b;
state[
2 +=  c;
state[
3 +=  d;

}


/* Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的,
  只拆低32bit,以适应原始C实现的用途
*/

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数组按顺序合成成long数组,因为java的long类型是64bit的,
  只合成低32bit,高32bit清零,以适应原始C实现的用途
*/

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是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算
*/

public   static   long  b2iu( byte  b)  {
return  b  <   0   ?  b  &   0x7F   +   128  : b;
}


/* byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示,
 因为java中的byte的toString无法实现这一点,我们又没有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 ) 评论( 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 
/**  
* 对字符串进行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; 
}
 
}
 

posted on 2007-05-01 22:21 duansky 阅读(445) 评论(0)  编辑  收藏 所属分类: Java


只有注册用户登录后才能发表评论。


网站导航: