收集于網絡
MD5簡介:
MD5的全稱是Message-Digest Algorithm 5,在90年代初由MIT的計算機科學實驗室和RSA Data Security Inc發明,經MD2、MD3和MD4發展而來。
Message-Digest泛指字節串(Message)的Hash變換,就是把一個任意長度的字節串變換成一定長的大整數。請注意我使用了“字節串”而不是“字符串”這個詞,是因為這種變換只與字節的值有關,與字符集或編碼方式無關。
MD5將任意長度的“字節串”變換成一個128bit的大整數,并且它是一個不可逆的字符串變換算法,(我剛開始還愚蠢的認為MD5是可逆的算法感謝Stkman大哥的講解)換句話說就是,即使你看到源程序和算法描述,也無法將一個MD5的值變換回原始的字符串,從數學原理上說,是因為原始的字符串有無窮多個,這有點象不存在反函數的數學函數。
MD5的典型應用是對一段Message(字節串)產生fingerprint(指紋),以防止被“篡改”。舉個例子,你將一段話寫在一個叫readme.txt文件中,并對這個readme.txt產生一個MD5的值并記錄在案,然后你可以傳播這個文件給別人,別人如果修改了文件中的任何內容,你對這個文件重新計算MD5時就會發現。如果再有一個第三方的認證機構,用MD5還可以防止文件作者的“抵賴”,這就是所謂的數字簽名應用。
MD5還廣泛用于加密和解密技術上,在很多操作系統中,用戶的密碼是以MD5值(或類似的其它算法)的方式保存的,用戶Login的時候,系統是把用戶輸入的密碼計算成MD5值,然后再去和系統中保存的MD5值進行比較,而系統并不“知道”用戶的密碼是什么。
一些黑客破獲這種密碼的方法是一種被稱為“跑字典”的方法。有兩種方法得到字典,一種是日常搜集的用做密碼的字符串表,另一種是用排列組合方法生成的,先用MD5程序計算出這些字典項的MD5值,然后再用目標的MD5值在這個字典中檢索。
即使假設密碼的最大長度為8,同時密碼只能是字母和數字,共26+26+10=62個字符,排列組合出的字典的項數則是P(62,1)+P(62,2)….+P(62,8),那也已經是一個很天文的數字了,存儲這個字典就需要TB級的磁盤組,而且這種方法還有一個前提,就是能獲得目標賬戶的密碼MD5值的情況下才可以。
在軟件的加密保護中 很多軟件采用MD5保護 但是由于MD5算法為不可逆算法所以所有的軟件都是使用MD5算法作為一個加密的中間步驟,比如對用戶名做一個MD5變換,結果再進行一個可逆的加密變換,做注冊機時也只要先用MD5變換,然后再用一個逆算法。所以對于破解者來說只要能看出是MD5就很容易了。
MD5代碼的特點明顯,跟蹤時很容易發現,如果軟件采用MD5算法,在數據初始化的時候必然用到以下的四個常數
0x67452301;
0xefcdab89;
0x98badcfe;
0x10325476;
若常數不等 則可能是變形的MD5算法 或者根本就不是這個算法。在內存了也就是
01 23 45 67 89 ab cd ef fe dc ......32 10 16個字節
————————————————————————————————————————————
MD5算法:
第一步:增加填充
增加padding使得數據長度(bit為單位)模512為448。如果數據長度正好是模512為448,增加512個填充bit,也就是說填充的個數為1-512。第一個bit為1,其余全部為0。
第二步:補足長度
將數據長度轉換為64bit的數值,如果長度超過64bit所能表示的數據長度的范圍,值保留最后64bit,增加到前面填充的數據后面,使得最后的數據為512bit的整數倍。也就是32bit的16倍的整數倍。在RFC1321中,32bit稱為一個word。
第三步:初始化變量:
用到4個變量,分別為A、B、C、D,均為32bit長。初始化為:
A: 01 23 45 67
B: 89 ab cd ef
C: fe dc ba 98
D: 76 54 32 10
第四步:數據處理:
首先定義4個輔助函數:
F(X,Y,Z) = XY v not(X) Z
G(X,Y,Z) = XZ v Y not(Z)
H(X,Y,Z) = X xor Y xor Z
I(X,Y,Z) = Y xor (X v not(Z))
其中:XY表示按位與,X v Y表示按位或,not(X)表示按位取反。xor表示按位異或。
函數中的X、Y、Z均為32bit。
定義一個需要用到的數組:T(i),i取值1-64,T(i)等于abs(sin(i))的4294967296倍的整數部分,i為弧度。
假設前三步處理后的數據長度為32*16*Nbit
第五步:輸出:
最后得到的ABCD為輸出結果,共128bit。A為低位,D為高位。 MD5在編程中的實現--JAVA
/************************************************
MD5?算法的Java?Bean
*************************************************/
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)?{
????????????????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的主計算過程,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
????????????????????????i?=?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?*/
????????????????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數組按順序拆成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;
????????}
????????public?static?void?main(String?args[])?{
????????????????MD5?m?=?new?MD5();
????????????????if?(Array.getLength(args)?==?0)?{???//如果沒有參數,執行標準的Test?Suite
???????????????????????????System.out.println("MD5?Test?suite:");
????????????????????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(\"message?digest\"):"+m.getMD5ofStr("message?digest"));
????????????????????System.out.println("MD5(\"abcdefghijklmnopqrstuvwxyz\"):"+
????????????????????????m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz"));
????????????????????System.out.println("MD5(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"):"+
?????????????????????????m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
????????????????????
????????????????????
????????????????}
????????????????else
??????????????????????????System.out.println("MD5("?+?args[0]?+?")="?+?m.getMD5ofStr(args[0]));
????????????????String?a=m.getMD5ofStr(new?String("jkz"));
????????????????System.out.print(a+"?"+a.equals(m.getMD5ofStr(new?String("aaaa"))));
????????}
}
posted on 2006-11-24 21:12
流浪汗 閱讀(938)
評論(0) 編輯 收藏 所屬分類:
Java