MD5:
在上一篇《Servlet的學習之Session(5)》中,為了能使獲取的所有隨機數都能有相同的位數,我們采用MD5獲取隨機數的消息摘要(或稱數據指紋、數據摘要等等)。
MD5可以將所有的數字組合進行一個算法的運算得出一個新的數字組合,並且這個新的數字組合都是128位,也稱為MD5碼。MD5碼是不可逆的,即無法通過MD5碼來進行反向運算得到原始的數據。MD5的應用場合非常多,比如保存用戶密碼(防止數據庫中用戶密碼被管理員看到,所以數據庫中的密碼不許使用明文密碼),或者文件校驗(防止下載的文件是被別人修改后的文件而不是官方原文件,比如蘋果開發工具的XCodeGhost事件),或者光盤破損校驗等等。
在Java中通過MessageDigest對象來調用方法獲取某些數字組合的MD5碼(順便說一句,MessageDigest也可以用來獲取SHA校驗碼)。通過MessageDigest對象調用digest方法來將數字組合轉變為字符數組:
1 String data = "1"; 2 3 MessageDigest md = MessageDigest.getInstance("md5"); 4 byte[] md5 = md.digest(data.getBytes()); 5 6 System.out.println(Arrays.toString(md5));
獲得的字節數組都是128位,即16字節。換句話說經過MD5后的字符數組中有16個元素,因為Java中byte的范圍為-128~127,所以每個元素都在這范圍內:
注意,經過md5后的字符數組中含有負數元素,因此如果將這個字符數組進行轉換成字符串,查詢GB2312或者UTF-8都是不合適的會出現亂碼例如:
1 String sData = new String(md5,"utf-8"); 2 System.out.println(sData);
那么我們將如何使這個字節數組轉換成一個沒有亂碼的字符串作為一種隨機數?我們可以采用“Base64”編碼。
Base64編碼:
Base64編碼是把每3個8位字節(3*8=24)轉成4個6位字節(4*6=24),且在每個6位字節前補兩個0,重新形成8位一個字節的形式,這樣總的長度還是相同的,並且保證最高位不是1(即不是負數)。
如果最后剩下的字符不足3個字符,則用0填充高位,輸出字符使用“=”。因此編碼后的字符串末尾可能會出現一個或兩個“=”。
根據上述原理,最高兩位均為0,那么剩下6位全為1二進制對應的十進制為63,所以最大數不會超過63,根據這64個數進行一個碼值與字符的對應,就成了base64編碼,對應編碼表如下圖所示:
在Java中我們使用BASE64Encoder對象調用encode方法來將某個字節數組進行編碼。
我們將上面的MD5碼進行base64編碼:
1 BASE64Encoder be = new BASE64Encoder(); 2 String base64 = be.encode(md5); 3 System.out.println(base64);
可以看到這時將亂碼都對應成字符了:
注意,BASE64Encoder無法查看其API文檔,因為sun公司沒有將其正式發布出來,也就沒有相應的javadoc文檔可以查閱。只能通過下載相應的jar包或者通過網上查閱,如果在開發IDE中發現無法找到sun.misc.BASE64Encode請在網上下載這個JAR包並導入即可。或者請看這篇博客的方法: 《BASE64Encoder及BASE64Decoder的正確用法》