原始碼
/**
* 類別名稱: MD5Digest<br>
* 說明: 用於進行密碼加密的md5公用參數<br>
* 編寫日期: 2001/03/05<br>
* 修改者: <br>
* 修改訊息: <br>
* @作者edgarlo [email protected]
* @版本1.0<br>
*/
導入 java.security.MessageDigest;
導入java.security.NoSuchAlgorithmException;
公開課 MD5Digest
{
私有 MessageDigest __md5 = null;
私有 StringBuffer __digestBuffer = null;
公共 MD5Digest()
拋出 NoSuchAlgorithmException
{
__md5 = MessageDigest.getInstance("MD5");
__digestBuffer = 新的 StringBuffer();
}
公有字串 md5crypt(字串 s)
{
__digestBuffer.setLength(0);
位元組abyte0[] = __md5.digest(s.getBytes());
for(int i = 0; i < abyte0.length; i++)
__digestBuffer.append(toHex(abyte0[i]));
返回 __digestBuffer.toString();
}
公共字串 toHex(位元組一){
字串十六進位=“0123456789ABCDEF”;
char[] 結果=新的char[2];
結果[0]=HEX.charAt((one & 0xf0) >> 4);
結果[1]=HEX.charAt(一&0x0f);
字串mm=新字串(結果);
返回毫米;
}
}
-------------------------------------------------- ------------------------------------------
/************************************************* *******
MD5 演算法的 Java Bean
@作者:Topcat Tuppin
最後修改時間:2001 年 3 月 10 日
************************************************** ****/
打包熊工具;
導入 java.lang.reflect.*;
/************************************************* *******
md5類別實作了RSA Data Security, Inc.在提交給IETF
的RFC1321中的MD5訊息摘要演算法。
************************************************** ****/
公共類別 MD5 {
/* 下面這些S11-S44其實是一個4*4的矩陣,在原始的C實作中是用#define實現的,
這裡把它們實現成為靜態最終是表示了有趣,切能在同一個進程空間內的多個
實例間共用*/
靜態最終 int S11 = 7;
靜態最終 int S12 = 12;
靜態最終 int S13 = 17;
靜態最終 int S14 = 22;
靜態最終 int S21 = 5;
靜態最終 int S22 = 9;
靜態最終 int S23 = 14;
靜態最終 int S24 = 20;
靜態最終 int S31 = 4;
靜態最終 int S32 = 11;
靜態最終 int S33 = 16;
靜態最終 int S34 = 23;
靜態最終 int S41 = 6;
靜態最終 int S42 = 10;
靜態最終 int S43 = 15;
靜態最終 int S44 = 21;
靜態最終位元組[] 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結構中
*/
私有long[]狀態=新long[4]; // 狀態 (ABCD)
private 長[] count = new 長[2]; // 位數,模 2^64(lsb 在前)
私有位元組[]緩衝區=新位元組[64]; // 輸入緩衝區
/*digestHexStr是MD5的唯一一個公共成員,是最近一次計算結果的16ASCII表示。
*/
公共字串摘要HexStr;
/*摘要,是最近一次計算結果的2內部表示,表示128bit的MD5值。
*/
私有字節[]摘要=新字節[16];
/*
getMD5ofStr是類別MD5統計的公共方法,入口參數是你想要進行MD5變換的字串
回傳的是轉換完成的結果,這個結果是從公共成員digestHexStr 取得的.
*/
公有字串 getMD5ofStr(字串 inbuf) {
md5Init();
md5Update(inbuf.getBytes(), inbuf.length());
md5Final();
摘要HexStr =“”;
for (int i = 0; i < 16; i++) {
摘要HexStr += byteHEX(digest[i]);
}
返回摘要HexStr;
}
// 這是MD5這類的標準建構函數,JavaBean要求有一個public的且沒有參數的建構函數
公共 MD5() {
md5Init();
返回;
}
/* md5Init是初始化函數,初始化核心變量,導入標準的變數 */
私有無效 md5Init() {
計數[0] = 0L;
計數[1] = 0L;
///* 載入魔法初始化常數。
狀態[0] = 0x67452301L;
狀態[1] = 0xefcdab89L;
狀態[2] = 0x98badcfeL;
狀態[3] = 0x10325476L;
返回;
}
/* F, G, H ,I 是4個基本的MD5函數,在原始的MD5的C實現中,由於它們是
簡單的位置,可能出於效率的考慮把它們實現成了宏,在java中,我們把它們
實作成了private方法,名字保留了原來C中的
。
返回 (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));
}
/*
FF,GG,HH和II將調用F,G,H,I進行近一步變換
第 1、2、3 和 4 輪的 FF、GG、HH 和 II 轉換。
旋轉與加法分開,以防止重新計算。
*/
私有長 FF(長 a, 長 b, 長 c, 長 d, 長 x, 長 s,
長交流){
a+=F(b,c,d)+x+ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a+=b;
返回一個;
}
私有長 GG(長 a, 長 b, 長 c, 長 d, 長 x, 長 s,
長交流){
a+=G(b,c,d)+x+ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a+=b;
返回一個;
}
私有長HH(長a,長b,長c,長d,長x,長s,
長交流){
a+=H(b,c,d)+x+ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a+=b;
返回一個;
}
私有長II(長a,長b,長c,長d,長x,長s,
長交流){
a+=I(b,c,d)+x+ac;
a = ((int) a << s) | ((int) a >>> (32 - s));
a+=b;
返回一個;
}
/*
md5Update是MD5的主要計算過程,inbuf是要轉換的位元組串,inputlen是長度,這個
函數由getMD5ofStr調用,呼叫之前需要呼叫md5init,因此把它設計成私有的
*/
私有無效 md5Update(byte[] inbuf, int inputLen) {
int i,index,partLen;
字節[]塊=新字節[64];
索引 = (int)(count[0] >>> 3) & 0x3F;
// /* 更新位數 */
if ((count[0] += (inputLen << 3)) < (inputLen << 3))
計數[1]++;
計數[1] += (inputLen >>> 29);
部分長度 = 64 - 索引;
// 盡可能變換。
if (inputLen >= partLen) {
md5Memcpy(緩衝區,inbuf,索引,0,partLen);
md5Transform(緩衝區);
for (i = partLen; i + 63 < inputLen; i += 64) {
md5Memcpy(block, inbuf, 0, i, 64);
md5Transform(區塊);
}
索引=0;
否則
我 = 0;
///* 緩衝區剩餘輸入 */
md5Memcpy(緩衝區, inbuf, 索引, i, inputLen - i);
}
/*
md5最終整理並填寫輸出結果
*/
私有無效 md5Final () {
字節[]位元=新字節[8];
int索引,padLen;
///* 保存位數 */
編碼(位數,計數,8);
///* 填入 56 mod 64。
索引 = (int)(count[0] >>> 3) & 0x3f;
padLen = (索引 < 56) ? (56 - 索引):(120 - 索引);
md5Update(PADDING, padLen);
///* 附加長度(填滿前)*/
md5Update(位元, 8);
///* 將狀態儲存在摘要中 */
編碼(摘要、狀態、16);
}
/* md5Memcpy是一個內部使用的位元組拷貝的區塊拷貝函數,從輸入的inpos開始把len長度的位元組拷貝到輸出的outpos位置開始
*/
private void md5Memcpy (byte[] 輸出, byte[] 輸入,
int outpos、int inpos、int len)
{
整數我;
for (i = 0; i < len; i++)
輸出[outpos + i] = 輸入[inpos + i];
}
/*
md5Transform是MD5核心轉換程序,有md5Update調用,block是分塊的原始位元組
*/
私有無效 md5Transform (位元組區塊[]) {
長a=狀態[0],b=狀態[1],c=狀態[2],d=狀態[3];
長[] x = 新長[16];
解碼(x,塊,64);
/* 第一輪 */
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 */
/* 第 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 */
/* 第三輪 */
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 */
/* 第 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 */
狀態[0] += a;
狀態[1] += b;
狀態[2] += c;
狀態[3] += d;
}
/*Encode把long內存依序拆成byte內存,因為java的long型別是64bit的,
只拆掉低32位,以適應原始C實現的用途
*/
private void Encode (byte[] 輸出, 長[] 輸入, int len) {
整數 i,j;
for (i = 0, j = 0; j < len; i++, j += 4) {
輸出[j] = (位元組)(輸入[i] & 0xffL);
輸出[j + 1] = (位元組)((輸入[i] >>> 8) & 0xffL);
輸出[j + 2] = (位元組)((輸入[i] >>> 16) & 0xffL);
輸出[j + 3] = (位元組)((輸入[i] >>> 24) & 0xffL);
}
}
/*解碼把位元組佇列依序合成成長佇列,因為java的長型別是64位元的,
只合成低32位,高32位清零,以適應原始C實現的用途
*/
private void Decode (長[] 輸出, byte[] 輸入, int len) {
整數 i,j;
for (i = 0, j = 0; j < len; i++, j += 4)
輸出[i] = b2iu(輸入[j]) |
(b2iu(輸入[j + 1]) << 8) |
(b2iu(輸入[j + 2]) << 16) |
(b2iu(輸入[j + 3]) << 24);
返回;
}
/*
b2iu是我寫的一個依照位元組不考慮正負號原則的「升位」程序,因為java沒有無符號攻擊
*/
公共靜態長b2iu(位元組b){
回傳 b < 0 ? b & 0x7F + 128 : b;
}
/*byteHEX(),用來把一個位元組類型的數轉換成十六進位的ASCII表示,
因為java中的byte的toString無法實現這一點,我們又沒有C語言中的
sprintf(outbuf,"%02X",ib)
*/
公共靜態字串 byteHEX(位元組 ib) {
char[] 數字 = { '0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F' };
char[] ob = new char[2];
ob[0] = 數字[(ib >>> 4) & 0X0F];
ob[1] = 數字[ib & 0X0F];
字串 s = new String(ob);
返回 s;
}
公共靜態無效主(字串參數[]){
MD5 m = 新 MD5();
if (Array.getLength(args) == 0) { //如果沒有參數,執行標準的測試套件
System.out.println("MD5 測試套件:");
System.out.println("MD5(""):"+m.getMD5ofStr(""));
System.out.println("MD5("a"):"+m.getMD5ofStr("a"));
System.out.println("MD5("abc"):"+m.getMD5ofStr("abc"));
System.out.println("MD5("訊息摘要"):"+m.getMD5ofStr("訊息摘要"));
System.out.println("MD5("abcdefghijklmnopqrstuvwxyz"):"+
m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz"));
System.out.println("MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"):"+
m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
}
別的
System.out.println("MD5(" + args[0] + ")=" + m.getMD5ofStr(args[0]));
}
}
JSP中的使用方法
--------------------------------------------- ----------- ----------------------------------
<%@頁面語言='java'%>
<jsp:useBean id='oMD5' scope='request' class='beartool.MD5'/>
<%@ page import='java.util.*'%>
<%@頁面導入='java.sql.*'%>
<html>
<正文>
<%
String userid = request.getParameter("用戶ID"); //取得使用者輸入UserID
String 密碼 = request.getParameter("密碼"); //取得輸入使用者的密碼
字串 pwdmd5 = oMD5.getMD5ofStr(密碼); //計算MD5的值
PrintWriter rp = response.getWriter();
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
連接 con = DriverManager.getConnection("jdbc:odbc:community", "", "");
語句 stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("從 userID ='"+userid+"' 和 pwdmd5= '" + pwdmd5+"'" 的使用者中選擇*);
if (rs.next())
{
rp.print("登入成功");
}
別的
{
rp.print("登入失敗");
stmt.close
();
con.close();
%>
</body>
</html>