java MD5 并发
Message Digest Algorithm MD5(中文名為消息摘要算法第五版)為計算機安全領域廣泛使用的一種散列函數,用以提供消息的完整性保護。該算法的文件號為RFC 1321(R.Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc. April 1992)。
查看MessageDigest源碼
public void update(byte[] input) {engineUpdate(input, 0, input.length);state = IN_PROGRESS; }可以看到這里調用了engineUpdate方法,此方法進行一個更新操作。
然后state屬性的狀態就被改變了,表明當前計算正在處理過程中。
state默認屬性
private int state = INITIAL;
然后需要調用MessageDigest.digest()方法計算哈希值
public byte[] digest() {/* Resetting is the responsibility of implementors. */byte[] result = engineDigest();state = INITIAL;return result; }
到這里已經完成了MD5值的計算,state屬性恢復初始狀態,如果想要重用MessageDigest對象,還需要調用MessageDigest.reset()方法進行重置,以免這次計算數據會對下一次的計算造成影響,從而導致計算結果錯誤。
而我所遇到的問題就是,在MessageDigest在多線程的環境下,Thread-1的計算還沒有完成的情況下,Thread-2又開始使用該MessageDigest對象進行下一次的計算,Thread-2修改了MessageDigest的狀態,Thread-1使用被修改過后的MessageDigest進行計算,從而導致了計算結果錯誤。
解決方案有兩個:
1、加鎖來共享同一個MessageDigest;
public class MD5 { private static final byte[] ToHex_ = { '0','1','2','3','4','5','6','7', '8','9','a','b','c','d','e','f' }; private MessageDigest md5_ = null; static private MessageDigest Md5_; static { try { Md5_ = MessageDigest.getInstance("MD5");} // MD5 is supported catch ( NoSuchAlgorithmException e ) {}; // safe to swallow };public MD5() { try { md5_ = MessageDigest.getInstance("MD5");} // MD5 is supported catch ( NoSuchAlgorithmException e ) {}; // safe to swallow } /** * */ public static synchronized String Digest(byte[] dataToHash) { Md5_.update(dataToHash, 0, dataToHash.length); return HexStringFromBytes( Md5_.digest() ); } /** * Non-threadsafe MD5 digest (hashing) function */ public String digest(byte[] dataToHash) { md5_.update(dataToHash, 0, dataToHash.length); return HexStringFromBytes( md5_.digest() ); } private static String HexStringFromBytes(byte[] b) { byte [] hex_bytes = new byte[ b.length * 2 ]; int i,j=0; for (i=0; i < b.length; i++) { hex_bytes[j] = ToHex_[ ( b[i] & 0xF0 ) >> 4 ] ; hex_bytes[j+1] = ToHex_[ b[i] & 0xF ]; j+=2; } return new String( hex_bytes ); } }
2、每次新創建一個MessageDigest;
class MD5_test { public final static String MD5(String s) { char hexDigits[] = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' }; try { byte [] strTemp = s.getBytes(); MessageDigest mdTemp = MessageDigest.getInstance("MD5" ); mdTemp.update(strTemp); byte [] md = mdTemp.digest(); int j = md.length; char str[] = new char [j * 2 ]; int k = 0 ; for ( int i = 0 ; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf ]; str[k++] = hexDigits[byte0 & 0xf ]; } return new String(str); } catch (Exception e) { return null ; } } public static void main(String[] args) { // MD5_Test aa = new MD5_Test(); System.out.print(MD5_test.MD5("a" )); // System.out.print(MD5_test.MD5("%7B%7DAHRCU" )); } }
這兩種方案都可解決并發問題。
轉載于:https://www.cnblogs.com/xujishou/p/8044339.html
總結
以上是生活随笔為你收集整理的java MD5 并发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为确保Bard能给出高质量答案 谷歌员工
- 下一篇: ConstraintLayout 学习笔