因爲MD5的不可逆,因此有的網站會把密碼轉換MD5,而後存儲。可是這種算法並非100%嚴密的,參考MD5 - 維基百科java
下面就寫寫MD5在Java中的使用。git
主要分爲四步算法
定義一個char數組,存儲16進制的基本字符數組
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
其中的英語字符能夠大寫也能夠小寫,取決於你要的結果是大寫仍是小寫。好比網站
123456轉換後加密
大寫是E10ADC3949BA59ABBE56E057F20F883Espa
小寫是e10adc3949ba59abbe56e057f20f883e.net
獲取Java中的MD5類,用於把輸入的字符進行信息摘要運算,獲得一個byte數組。
code
MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } md.reset(); md.update(str.getBytes()); byte[] bArray = md.digest();
這個byte數組是2進制的數據,下一步咱們要把2進制轉換成16進制
orm
轉換16進制,這一步是關鍵
protected static char[] encodeHex ( final byte[] data, final char[] toDigits){ final int len = data.length; final char[] out = new char[len << 1]; for (int i = 0, j = 0; i < len; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return out; }
<< 和 >>> 都是java的位移操做符
在說明以前須要解釋一下2進制到16進制的轉換,
把data[i]的高四位(data[i]>>>4) 和0xF0作 & 運算((0xF0 & data[i]) >>> 4),獲得16進制高1位
把data[i]的低四位(data[i]) 和0xF0作 & 運算,獲得16進制低1位
上面兩句獲得的值都是0到15,這樣就獲得toDigits數組的位置對應的字符。
final char[] out = new char[len << 1];
這個語句表示要定義一個輸出數組(out[]),長度是須要轉換數組(date[])的2倍。
爲何要是2倍呢,由於2進制的128位,要對應16進制的32位,一個byte是八位二進制,也就是2位十六進制字符(2的8次方等於16的2次方)
最後一步就是把獲得的char數組轉換成字符串輸出。
下面是完整代碼
public static String StringMD5(String str){ char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } md.reset(); md.update(str.getBytes()); byte[] bArray = md.digest(); String finalStr = new String(encodeHex(bArray, hexDigits)); System.out.println("16位大寫:" + finalStr.substring(8, 24)); System.out.println("32位大寫:" + finalStr); return finalStr; } protected static char[] encodeHex ( final byte[] data, final char[] toDigits){ final int len = data.length; final char[] out = new char[len << 1]; for (int i = 0, j = 0; i < len; i++) { out[j++] = toDigits[(0xF0 & data[i]) >>> 4]; out[j++] = toDigits[0x0F & data[i]]; } return out; }
補充幾點:網上有不少Java中MD5的加密實現,和本文所提內容主要區別就是2進制轉換16進制
本文是本身寫的2進制轉換16進制,網上的大部分是利用了java的方法直接轉換的,好比
Integer.toHexString(bt)
因此碰到這些也不要迷惑,只是實現不一樣而已。
代碼下載地址MD5加密實現