一文搞懂Java MD5算法的原理及實(shí)現(xiàn)
MD5加密簡介
哈希算法又稱散列算法,是將任何數(shù)據(jù)轉(zhuǎn)換成固定長度的算法的統(tǒng)稱。 從本質(zhì)上講,MD5也是一種哈希算法,其輸出是生成128位的輸出結(jié)果。 如果輸入兩個(gè)不同的明文,就會(huì)輸出兩個(gè)不同的輸出值,并且根據(jù)輸出值,不能得到原始的明文,這個(gè)過程是不可逆的。
MD5加密原理
MD5算法對512位報(bào)文的輸入信息進(jìn)行處理,每個(gè)報(bào)文被分成16個(gè)32位報(bào)文。 經(jīng)過一系列處理后,算法的輸出由4個(gè)32位的數(shù)據(jù)包組成,這些數(shù)據(jù)包級聯(lián)生成一個(gè)128位的哈希值。
在MD5算法中,信息的填寫方式是這樣的:消息后面跟著一個(gè)1,然后是無數(shù)個(gè)0,直到512字節(jié)的剩余數(shù)等于448 (n*512) + 448。 為什么剩下的是448,因?yàn)槭O碌?12-448是64位,表示填充前的消息長度。 加上剩下的64位,(n+1)乘以512,也就是512的整數(shù)倍。
然后循環(huán)通過link變量獲得結(jié)果。 MD5包含四個(gè)32位整數(shù)參數(shù),稱為鏈接變量:A=0x01234567, B= 0x89ABCdef, C= 0xFeDCba98, D=0x76543210。 一旦設(shè)置好四個(gè)鏈接變量,算法就開始了四輪循環(huán)。 具體的內(nèi)部計(jì)算是關(guān)于數(shù)學(xué)的。如果你感興趣,你可以自己理解。這里沒有更多的解釋。
MD5加密常用方法
/** * 用MD5算法進(jìn)行加密 * @param str 需要加密的字符串 * @return MD5加密后的結(jié)果 * @throws UnsupportedEncodingException */ public static String encodeMD5String(String str) { return getMD5(str); }
/** * MD5編碼方法, 該方法存在漏洞,特殊情況下編碼后的字符串只有31位長度 * @param str * @param method * @return * @throws UnsupportedEncodingException */ private static String encode(String str, String method) throws UnsupportedEncodingException { MessageDigest md = null; String dstr = null; try { md = MessageDigest.getInstance(method); md.update(str.getBytes("UTF-8")); dstr = new BigInteger(1, md.digest()).toString(16); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return dstr; }
/** * MD5編碼方法 * @param message * @return */ public static String getMD5(String message) { MessageDigest messageDigest = null; StringBuffer md5StrBuff = new StringBuffer(); try { messageDigest = MessageDigest.getInstance("MD5"); messageDigest.reset(); messageDigest.update(message.getBytes("UTF-8")); byte[] byteArray = messageDigest.digest(); for (int i = 0; i < byteArray.length; i++) { if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i])); else md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i])); } } catch (Exception e) { throw new RuntimeException(); } return md5StrBuff.toString().toUpperCase();//字母大寫 }
/** * 加密 * @param content * @return */ public static String encrypt(String content) { String password = "12345678dd"; byte[] encryptResult = encrypt(content, password); String encryptResultStr = parseByte2HexStr(encryptResult); return encryptResultStr; }
/** * 加密 * @param content * @param password * @return */ public static String encryptStr(String content, String password) { byte[] encryptResult = encrypt(content, password); return parseByte2HexStr(encryptResult); }
/** * 解密 * @param encryptResultStr * @return * @throws UnsupportedEncodingException */ public static String decrypt(String encryptResultStr) throws UnsupportedEncodingException { String password = "12345678dd"; byte[] decryptFrom = parseHexStr2Byte(encryptResultStr); byte[] decryptResult = decrypt(decryptFrom, password); // 解密內(nèi)容進(jìn)行解碼 String result = new String(decryptResult, UTF8); return result; }
/** * 解密 * @param encryptStr * @param password * @return * @throws UnsupportedEncodingException */ public static String decryptStr(String encryptStr, String password) throws UnsupportedEncodingException { byte[] decryptFrom = parseHexStr2Byte(encryptStr); byte[] decryptResult = decrypt(decryptFrom, password); // 解密內(nèi)容進(jìn)行解碼 return new String(decryptResult, UTF8); }
到此這篇關(guān)于一文搞懂Java MD5算法的原理及實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java MD5算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Logback+MyBatis日志輸出問題的一些思考
這篇文章主要介紹了關(guān)于Logback+MyBatis日志輸出問題的一些思考,具有很好的參考價(jià)值,希望對大家有所幫助,2023-09-09Springboot?格式化LocalDateTime的方法
這篇文章主要介紹了Springboot格式化LocalDateTime的相關(guān)知識,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05SpringCloud微服務(wù)之Hystrix組件實(shí)現(xiàn)服務(wù)熔斷的方法
微服務(wù)架構(gòu)特點(diǎn)就是多服務(wù),多數(shù)據(jù)源,支撐系統(tǒng)應(yīng)用。這樣導(dǎo)致微服務(wù)之間存在依賴關(guān)系。這篇文章主要介紹了SpringCloud微服務(wù)之Hystrix組件實(shí)現(xiàn)服務(wù)熔斷的方法,需要的朋友可以參考下2019-08-08Spring Boot集成Redis實(shí)現(xiàn)緩存機(jī)制(從零開始學(xué)Spring Boot)
這篇文章主要介紹了Spring Boot集成Redis實(shí)現(xiàn)緩存機(jī)制(從零開始學(xué)Spring Boot),需要的朋友可以參考下2017-04-04Netty分布式NioSocketChannel注冊到selector方法解析
這篇文章主要為大家介紹了Netty分布式源碼分析NioSocketChannel注冊到selector方法的解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03Java中ThreadLocal使用原理及Synchronized區(qū)別
ThreadLocal叫做線程變量,本文詳細(xì)的介紹了ThreadLocal使用原理及Synchronized區(qū)別,有需要的朋友可以參考一下,希望對你有所幫助。2023-05-05深入解讀Java代碼組織中的package包結(jié)構(gòu)
這篇文章主要介紹了Java代碼組織中的package包結(jié)構(gòu),是Java入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-03-03