`
yingyingol
  • 浏览: 742814 次
文章分类
社区版块
存档分类
最新评论

MD5 算法的Java Bean

 
阅读更多
  1. /************************************************
  2. MD5算法的JavaBean
  3. @author:killsun:170781
  4. LastModified:10,Mar,2002
  5. *************************************************/
  6. packagecom.HandcnCMS.utility;
  7. importjava.lang.reflect.*;
  8. /*************************************************
  9. md5类实现了RSADataSecurity,Inc.在提交给IETF
  10. 的RFC1321中的MD5message-digest算法。
  11. *************************************************/
  12. /************************************************
  13. 引用方法:
  14. 要importcom.XXX.util.MD5;
  15. 然后
  16. StringloginPassword;//存倒数据库中的密码
  17. Strings;//用户输入的密码
  18. MD5oMD5=newMD5();
  19. Stringpwdmd5=oMD5.getMD5ofStr(s);
  20. loginPassword=pwdmd5;
  21. *************************************************/
  22. publicclassMD5{
  23. /*下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define实现的,
  24. 这里把它们实现成为staticfinal是表示了只读,切能在同一个进程空间内的多个
  25. Instance间共享*/
  26. staticfinalintS11=7;
  27. staticfinalintS12=12;
  28. staticfinalintS13=17;
  29. staticfinalintS14=22;
  30. staticfinalintS21=5;
  31. staticfinalintS22=9;
  32. staticfinalintS23=14;
  33. staticfinalintS24=20;
  34. staticfinalintS31=4;
  35. staticfinalintS32=11;
  36. staticfinalintS33=16;
  37. staticfinalintS34=23;
  38. staticfinalintS41=6;
  39. staticfinalintS42=10;
  40. staticfinalintS43=15;
  41. staticfinalintS44=21;
  42. staticfinalbyte[]PADDING={-128,0,0,0,0,0,0,0,0,
  43. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  44. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  45. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  46. /*下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中
  47. 被定义到MD5_CTX结构中
  48. */
  49. privatelong[]state=newlong[4];//state(ABCD)
  50. privatelong[]count=newlong[2];//numberofbits,modulo2^64(lsbfirst)
  51. privatebyte[]buffer=newbyte[64];//inputbuffer
  52. /*digestHexStr是MD5的唯一一个公共成员,是最新一次计算结果的
  53.  16进制ASCII表示.
  54. */
  55. publicStringdigestHexStr;
  56. /*digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值.
  57. */
  58. privatebyte[]digest=newbyte[16];
  59. /*
  60. getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串
  61. 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的.
  62. */
  63. publicStringgetMD5ofStr(Stringinbuf){
  64. md5Init();
  65. md5Update(inbuf.getBytes(),inbuf.length());
  66. md5Final();
  67. digestHexStr="";
  68. for(inti=0;i<16;i++){
  69. digestHexStr+=byteHEX(digest[i]);
  70. }
  71. returndigestHexStr;
  72. }
  73. //这是MD5这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数
  74. publicMD5(){
  75. md5Init();
  76. return;
  77. }
  78. /*md5Init是一个初始化函数,初始化核心变量,装入标准的幻数*/
  79. privatevoidmd5Init(){
  80. count[0]=0L;
  81. count[1]=0L;
  82. ///*Loadmagicinitializationconstants.
  83. state[0]=0x67452301L;
  84. state[1]=0xefcdab89L;
  85. state[2]=0x98badcfeL;
  86. state[3]=0x10325476L;
  87. return;
  88. }
  89. /*F,G,H,I是4个基本的MD5函数,在原始的MD5的C实现中,由于它们是
  90. 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们
  91.   实现成了private方法,名字保持了原来C中的。*/
  92. privatelongF(longx,longy,longz){
  93. return(x&y)|((~x)&z);
  94. }
  95. privatelongG(longx,longy,longz){
  96. return(x&z)|(y&(~z));
  97. }
  98. privatelongH(longx,longy,longz){
  99. returnx^y^z;
  100. }
  101. privatelongI(longx,longy,longz){
  102. returny^(x|(~z));
  103. }
  104. /*
  105. FF,GG,HH和II将调用F,G,H,I进行近一步变换
  106. FF,GG,HH,andIItransformationsforrounds1,2,3,and4.
  107. Rotationisseparatefromadditiontopreventrecomputation.
  108. */
  109. privatelongFF(longa,longb,longc,longd,longx,longs,
  110. longac){
  111. a+=F(b,c,d)+x+ac;
  112. a=((int)a<<s)|((int)a>>>(32-s));
  113. a+=b;
  114. returna;
  115. }
  116. privatelongGG(longa,longb,longc,longd,longx,longs,
  117. longac){
  118. a+=G(b,c,d)+x+ac;
  119. a=((int)a<<s)|((int)a>>>(32-s));
  120. a+=b;
  121. returna;
  122. }
  123. privatelongHH(longa,longb,longc,longd,longx,longs,
  124. longac){
  125. a+=H(b,c,d)+x+ac;
  126. a=((int)a<<s)|((int)a>>>(32-s));
  127. a+=b;
  128. returna;
  129. }
  130. privatelongII(longa,longb,longc,longd,longx,longs,
  131. longac){
  132. a+=I(b,c,d)+x+ac;
  133. a=((int)a<<s)|((int)a>>>(32-s));
  134. a+=b;
  135. returna;
  136. }
  137. /*
  138. md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个
  139. 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的
  140. */
  141. privatevoidmd5Update(byte[]inbuf,intinputLen){
  142. inti,index,partLen;
  143. byte[]block=newbyte[64];
  144. index=(int)(count[0]>>>3)&0x3F;
  145. ///*Updatenumberofbits*/
  146. if((count[0]+=(inputLen<<3))<(inputLen<<3))
  147. count[1]++;
  148. count[1]+=(inputLen>>>29);
  149. partLen=64-index;
  150. //Transformasmanytimesaspossible.
  151. if(inputLen>=partLen){
  152. md5Memcpy(buffer,inbuf,index,0,partLen);
  153. md5Transform(buffer);
  154. for(i=partLen;i+63<inputLen;i+=64){
  155. md5Memcpy(block,inbuf,0,i,64);
  156. md5Transform(block);
  157. }
  158. index=0;
  159. }else
  160. i=0;
  161. ///*Bufferremaininginput*/
  162. md5Memcpy(buffer,inbuf,index,i,inputLen-i);
  163. }
  164. /*
  165. md5Final整理和填写输出结果
  166. */
  167. privatevoidmd5Final(){
  168. byte[]bits=newbyte[8];
  169. intindex,padLen;
  170. ///*Savenumberofbits*/
  171. Encode(bits,count,8);
  172. ///*Padoutto56mod64.
  173. index=(int)(count[0]>>>3)&0x3f;
  174. padLen=(index<56)?(56-index):(120-index);
  175. md5Update(PADDING,padLen);
  176. ///*Appendlength(beforepadding)*/
  177. md5Update(bits,8);
  178. ///*Storestateindigest*/
  179. Encode(digest,state,16);
  180. }
  181. /*md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的
  182.      字节拷贝到output的outpos位置开始
  183. */
  184. privatevoidmd5Memcpy(byte[]output,byte[]input,
  185. intoutpos,intinpos,intlen)
  186. {
  187. inti;
  188. for(i=0;i<len;i++)
  189. output[outpos+i]=input[inpos+i];
  190. }
  191. /*
  192. md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节
  193. */
  194. privatevoidmd5Transform(byteblock[]){
  195. longa=state[0],b=state[1],c=state[2],d=state[3];
  196. long[]x=newlong[16];
  197. Decode(x,block,64);
  198. /*Round1*/
  199. a=FF(a,b,c,d,x[0],S11,0xd76aa478L);/*1*/
  200. d=FF(d,a,b,c,x[1],S12,0xe8c7b756L);/*2*/
  201. c=FF(c,d,a,b,x[2],S13,0x242070dbL);/*3*/
  202. b=FF(b,c,d,a,x[3],S14,0xc1bdceeeL);/*4*/
  203. a=FF(a,b,c,d,x[4],S11,0xf57c0fafL);/*5*/
  204. d=FF(d,a,b,c,x[5],S12,0x4787c62aL);/*6*/
  205. c=FF(c,d,a,b,x[6],S13,0xa8304613L);/*7*/
  206. b=FF(b,c,d,a,x[7],S14,0xfd469501L);/*8*/
  207. a=FF(a,b,c,d,x[8],S11,0x698098d8L);/*9*/
  208. d=FF(d,a,b,c,x[9],S12,0x8b44f7afL);/*10*/
  209. c=FF(c,d,a,b,x[10],S13,0xffff5bb1L);/*11*/
  210. b=FF(b,c,d,a,x[11],S14,0x895cd7beL);/*12*/
  211. a=FF(a,b,c,d,x[12],S11,0x6b901122L);/*13*/
  212. d=FF(d,a,b,c,x[13],S12,0xfd987193L);/*14*/
  213. c=FF(c,d,a,b,x[14],S13,0xa679438eL);/*15*/
  214. b=FF(b,c,d,a,x[15],S14,0x49b40821L);/*16*/
  215. /*Round2*/
  216. a=GG(a,b,c,d,x[1],S21,0xf61e2562L);/*17*/
  217. d=GG(d,a,b,c,x[6],S22,0xc040b340L);/*18*/
  218. c=GG(c,d,a,b,x[11],S23,0x265e5a51L);/*19*/
  219. b=GG(b,c,d,a,x[0],S24,0xe9b6c7aaL);/*20*/
  220. a=GG(a,b,c,d,x[5],S21,0xd62f105dL);/*21*/
  221. d=GG(d,a,b,c,x[10],S22,0x2441453L);/*22*/
  222. c=GG(c,d,a,b,x[15],S23,0xd8a1e681L);/*23*/
  223. b=GG(b,c,d,a,x[4],S24,0xe7d3fbc8L);/*24*/
  224. a=GG(a,b,c,d,x[9],S21,0x21e1cde6L);/*25*/
  225. d=GG(d,a,b,c,x[14],S22,0xc33707d6L);/*26*/
  226. c=GG(c,d,a,b,x[3],S23,0xf4d50d87L);/*27*/
  227. b=GG(b,c,d,a,x[8],S24,0x455a14edL);/*28*/
  228. a=GG(a,b,c,d,x[13],S21,0xa9e3e905L);/*29*/
  229. d=GG(d,a,b,c,x[2],S22,0xfcefa3f8L);/*30*/
  230. c=GG(c,d,a,b,x[7],S23,0x676f02d9L);/*31*/
  231. b=GG(b,c,d,a,x[12],S24,0x8d2a4c8aL);/*32*/
  232. /*Round3*/
  233. a=HH(a,b,c,d,x[5],S31,0xfffa3942L);/*33*/
  234. d=HH(d,a,b,c,x[8],S32,0x8771f681L);/*34*/
  235. c=HH(c,d,a,b,x[11],S33,0x6d9d6122L);/*35*/
  236. b=HH(b,c,d,a,x[14],S34,0xfde5380cL);/*36*/
  237. a=HH(a,b,c,d,x[1],S31,0xa4beea44L);/*37*/
  238. d=HH(d,a,b,c,x[4],S32,0x4bdecfa9L);/*38*/
  239. c=HH(c,d,a,b,x[7],S33,0xf6bb4b60L);/*39*/
  240. b=HH(b,c,d,a,x[10],S34,0xbebfbc70L);/*40*/
  241. a=HH(a,b,c,d,x[13],S31,0x289b7ec6L);/*41*/
  242. d=HH(d,a,b,c,x[0],S32,0xeaa127faL);/*42*/
  243. c=HH(c,d,a,b,x[3],S33,0xd4ef3085L);/*43*/
  244. b=HH(b,c,d,a,x[6],S34,0x4881d05L);/*44*/
  245. a=HH(a,b,c,d,x[9],S31,0xd9d4d039L);/*45*/
  246. d=HH(d,a,b,c,x[12],S32,0xe6db99e5L);/*46*/
  247. c=HH(c,d,a,b,x[15],S33,0x1fa27cf8L);/*47*/
  248. b=HH(b,c,d,a,x[2],S34,0xc4ac5665L);/*48*/
  249. /*Round4*/
  250. a=II(a,b,c,d,x[0],S41,0xf4292244L);/*49*/
  251. d=II(d,a,b,c,x[7],S42,0x432aff97L);/*50*/
  252. c=II(c,d,a,b,x[14],S43,0xab9423a7L);/*51*/
  253. b=II(b,c,d,a,x[5],S44,0xfc93a039L);/*52*/
  254. a=II(a,b,c,d,x[12],S41,0x655b59c3L);/*53*/
  255. d=II(d,a,b,c,x[3],S42,0x8f0ccc92L);/*54*/
  256. c=II(c,d,a,b,x[10],S43,0xffeff47dL);/*55*/
  257. b=II(b,c,d,a,x[1],S44,0x85845dd1L);/*56*/
  258. a=II(a,b,c,d,x[8],S41,0x6fa87e4fL);/*57*/
  259. d=II(d,a,b,c,x[15],S42,0xfe2ce6e0L);/*58*/
  260. c=II(c,d,a,b,x[6],S43,0xa3014314L);/*59*/
  261. b=II(b,c,d,a,x[13],S44,0x4e0811a1L);/*60*/
  262. a=II(a,b,c,d,x[4],S41,0xf7537e82L);/*61*/
  263. d=II(d,a,b,c,x[11],S42,0xbd3af235L);/*62*/
  264. c=II(c,d,a,b,x[2],S43,0x2ad7d2bbL);/*63*/
  265. b=II(b,c,d,a,x[9],S44,0xeb86d391L);/*64*/
  266. state[0]+=a;
  267. state[1]+=b;
  268. state[2]+=c;
  269. state[3]+=d;
  270. }
  271. /*Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的,
  272. 只拆低32bit,以适应原始C实现的用途
  273. */
  274. privatevoidEncode(byte[]output,long[]input,intlen){
  275. inti,j;
  276. for(i=0,j=0;j<len;i++,j+=4){
  277. output[j]=(byte)(input[i]&0xffL);
  278. output[j+1]=(byte)((input[i]>>>8)&0xffL);
  279. output[j+2]=(byte)((input[i]>>>16)&0xffL);
  280. output[j+3]=(byte)((input[i]>>>24)&0xffL);
  281. }
  282. }
  283. /*Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的,
  284. 只合成低32bit,高32bit清零,以适应原始C实现的用途
  285. */
  286. privatevoidDecode(long[]output,byte[]input,intlen){
  287. inti,j;
  288. for(i=0,j=0;j<len;i++,j+=4)
  289. output[i]=b2iu(input[j])|
  290. (b2iu(input[j+1])<<8)|
  291. (b2iu(input[j+2])<<16)|
  292. (b2iu(input[j+3])<<24);
  293. return;
  294. }
  295. /*
  296. b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算
  297. */
  298. publicstaticlongb2iu(byteb){
  299. returnb<0?b&0x7F+128:b;
  300. }
  301. /*byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示,
  302.  因为java中的byte的toString无法实现这一点,我们又没有C语言中的
  303. sprintf(outbuf,"%02X",ib)
  304. */
  305. publicstaticStringbyteHEX(byteib){
  306. char[]Digit={'0','1','2','3','4','5','6','7','8','9',
  307. 'a','b','c','d','e','f'};
  308. char[]ob=newchar[2];
  309. ob[0]=Digit[(ib>>>4)&0X0F];
  310. ob[1]=Digit[ib&0X0F];
  311. Strings=newString(ob);
  312. returns;
  313. }
  314. publicstaticvoidmain(Stringargs[]){
  315. MD5m=newMD5();
  316. if(Array.getLength(args)==0){//如果没有参数,执行标准的TestSuite
  317. System.out.println("MD5Testsuite:");
  318. System.out.println("MD5(/"10/"):"+m.getMD5ofStr("355694005457784"));
  319. System.out.println("MD5(/"11/"):"+m.getMD5ofStr("800922"));
  320. System.out.println("MB5(/"12/"):"+m.getMD5ofStr("781214"));
  321. System.out.println("MD5(/"13/"):"+m.getMD5ofStr("13"));
  322. System.out.println("MD5(/"messagedigest/"):"+m.getMD5ofStr("messagedigest"));
  323. System.out.println("MD5(/"abcdefghijklmnopqrstuvwxyz/"):"+
  324. m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz"));
  325. System.out.println("MD5(/"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/"):"+
  326. m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
  327. }
  328. else
  329. System.out.println("MD5("+args[0]+")="+m.getMD5ofStr(args[0]));
  330. }
  331. }
分享到:
评论

相关推荐

    jsp-MD5.rar_JSP MD5_md5.jsp

    JSP的MD5算法实现,MD5 算法之Java Bean

    [S036] MD5算法.rar

    介绍MD5加密算法基本情况MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2、MD3和MD4发展而来。 Message-Digest泛指字节串(Message)的Hash变换,就是...

    基于JAVA技术的MD5加密算法的设计与实现 (2009年)

    详细描述了在数字签名、电子商务、信息加密领域中广泛应用的MD5加密算法,并针对其高效、跨平台使用,提出利用JSP与Java Bean相结合的技术方法实现MD5加密算法。该方法采用Java语言实现MD5算法,并利用Java Bean组件...

    MD5计算检验工具 x64

    因此这些用户的密码对软件开发者或系统管理员来说可以说毫无保密可言,本文的目的是介绍MD5的Java Bean的实现,同时给出用MD5来处理用户的Account密码的例子,这种方法使得管理员和程序设计者都无法看到用户的密码,...

    MD5计算检验工具 x32

    因此这些用户的密码对软件开发者或系统管理员来说可以说毫无保密可言,本文的目的是介绍MD5的Java Bean的实现,同时给出用MD5来处理用户的Account密码的例子,这种方法使得管理员和程序设计者都无法看到用户的密码,...

    JAVA上百实例源码以及开源项目

     用JAVA开发的一个小型的目录监视系统,系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录中文件大小及文件增减数目的变化。 Java日期选择控件完整源代码 14个目标文件 内容索引:JAVA源码,系统相关,日历,...

    JAVA上百实例源码以及开源项目源代码

     用JAVA开发的一个小型的目录监视系统,系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录中文件大小及文件增减数目的变化。 Java日期选择控件完整源代码 14个目标文件 内容索引:JAVA源码,系统相关,日历,...

    java7hashmap源码-java-note:笔记

    算法 数据结构 设计模式 基础 集合 ConcurrentHashMap IO 并发 [Java 并发]( 并发.md) AQS 源码 JVM web 基础 [NGINX 简介](./docs/nginx/NGINX 简介.md) 框架 Spring [观察 Spring bean 实例化](./docs/spring/观察...

    JAVA程序开发大全---上半部分

    第5章 Java开发项目的软件测试工具——JUnit 68 5.1 软件测试简介 68 5.2 JUnit简介 68 5.2.1 JUnit的特点 69 5.2.2 JUnit的常用类和接口 69 5.3 在MyEclipse中设置JUnit 71 5.4 JUnit测试 72 5.4.1 JUnit测试用例 ...

    OnlineTest DEMO 开源说明[附源码]

    本程序并不是一套完整的系统,它只提供了一些基本的功能,发布并开源的目地只是为了java的初学者能更快的... 程序中的MD5加密部分使用了Topcat 、Tuppin、 yangtse所写的bean,其更详细的版权声明在PUBLICMD5.java中。

Global site tag (gtag.js) - Google Analytics