欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于MD5算法原理與常用實(shí)現(xiàn)方式

 更新時間:2022年08月18日 11:22:14   作者:zhangSir134  
這篇文章主要介紹了關(guān)于MD5算法原理與常用實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

定義

MD全稱Message-Digest,即信息摘要,所以MD家族的算法也叫信息摘要算法

MD家族有MD2、MD3、MD4、MD5,一代比一代強(qiáng)。

所以MD5是MD算法家族中,目前最常用的一種加密算法。

任何信息,都可以通過MD5算法運(yùn)算生成一個16字節(jié)(128位)的散列值,但卻無法通過這16個字節(jié)的散列值獲得加密前的信息。

最終這16個散列值,通常用一個長度為32的十六進(jìn)制字符串來表示。

這就是MD5最重要的一個特性:加密不可逆。

MD5特點(diǎn)

加密不可逆,即無法通過密文得到原文。

不變性,即相同的原文,通過MD5算法得到的密文總是相同的。

散列性,即對原文作輕微的改動,都可導(dǎo)致最終的密文完全改變。

常見應(yīng)用場景

1、校驗(yàn)文件的完整性

如果張三給李四傳了一個文件,如何確認(rèn)這個文件傳給李四是完整的呢

張三傳文件前,先對文件做一個MD5加密,同時把MD5加密的密文傳給李四

李四收到文件,也對該文件做MD5加密,如果得到的密文和張三給的密文一樣,就說明文件是完整的。

2、存儲用戶密碼

用戶密碼,理論上也不能直接明文存儲在數(shù)據(jù)庫中,因?yàn)橐坏?shù)據(jù)庫被破解,用戶的密碼就全部丟失了

所以可以將用戶密碼做一個MD5加密,然后將密文存在數(shù)據(jù)庫中

用戶登錄的時候,可以將用戶的密碼進(jìn)行MD5加密,然后比對密文和數(shù)據(jù)庫中的密文是否一致,來判斷用戶前臺填的密碼是否正確。

這只是一個思路,一般不會這么簡單,一般生產(chǎn)環(huán)境會對用戶密碼加鹽加密等等的處理,用戶信息更加重要的,則需要更加復(fù)雜的計算邏輯。

原理

MD5的加密過程,整體來看,就是先定義四個值,然后用這四個值,對原文信息進(jìn)行計算,并得到新的四個值,然后再對原文進(jìn)行計算,再得到新的四個值,如此循環(huán)一定次數(shù),最終對最后的這四個值進(jìn)行簡單的字符串拼接,就得到了最終的密文。

主要就是下面這3步:

1、填補(bǔ)信息

用原文長度位數(shù)對512求余,如果結(jié)果不為448,就填充到448位。填充是第一位填1,后面填0。512-448=64,用這剩余的64位,記錄原文長度。

最終得到一個填補(bǔ)完的信息(總長=原文長度+512位)

2、拿到初始值

四個初始值,是MD5這個算法提前定義好的,分別是4個32位的值,總共剛好128位。

我們用ABCD命名:

  • A=0x01234567
  • B=0x89ABCDEF
  • C=0xFEDCBA98
  • D=0x76543210

3、真正的計算

計算分為多次循環(huán),每次循環(huán),都是用ABCD和原文在第一步填補(bǔ)完的信息,進(jìn)行計算,最終得到新的ABCD。最后將最后一次ABCD拼成字符串,就是最終的密文。

  • 循環(huán)先分為主循環(huán),每個主循環(huán)中又套有子循環(huán)。
  • 主循環(huán)次數(shù) = 原文長度/512。
  • 子循環(huán)次數(shù) = 64次。

我們看看單次子循環(huán)都做了什么:

下面是單次子循環(huán)真正的計算邏輯(這段實(shí)現(xiàn)摘自網(wǎng)友):

在這里插入圖片描述

圖中,A,B,C,D就是哈希值的四個分組。每一次循環(huán)都會讓舊的ABCD產(chǎn)生新的ABCD。一共進(jìn)行多少次循環(huán)呢?由處理后的原文長度決定。

  • 假設(shè)處理后的原文長度是M
  • 主循環(huán)次數(shù) = M / 512
  • 每個主循環(huán)中包含 512 / 32 * 4 = 64 次 子循環(huán)。

上面這張圖所表達(dá)的就是單次子循環(huán)的流程。

下面對圖中其他元素一一解釋:

1.綠色F

圖中的綠色F,代表非線性函數(shù)。官方MD5所用到的函數(shù)有四種:

F(X, Y, Z) =(X&Y) | ((~X) & Z)
G(X, Y, Z) =(X&Z) | (Y & (~Z))
H(X, Y, Z) =X^Y^Z
I(X, Y, Z)=Y^(X|(~Z))

在主循環(huán)下面64次子循環(huán)中,F(xiàn)、G、H、I 交替使用,第一個16次使用F,第二個16次使用G,第三個16次使用H,第四個16次使用I。

2.紅色“田”字

很簡單,紅色的田字代表相加的意思。

3.Mi

Mi是第一步處理后的原文。在第一步中,處理后原文的長度是512的整數(shù)倍。把原文的每512位再分成16等份,命名為M0 ~ M15,每一等份長度32。在64次子循環(huán)中,每16次循環(huán),都會交替用到M1 ~ M16之一。

4.Ki

一個常量,在64次子循環(huán)中,每一次用到的常量都是不同的。

5.黃色的<<

FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)

<<<s表示循環(huán)左移s位

第一輪
 a=FF(a,b,c,d,M0,7,0xd76aa478)
 b=FF(d,a,b,c,M1,12,0xe8c7b756)
 c=FF(c,d,a,b,M2,17,0x242070db)
 d=FF(b,c,d,a,M3,22,0xc1bdceee)
 a=FF(a,b,c,d,M4,7,0xf57c0faf)
 b=FF(d,a,b,c,M5,12,0x4787c62a)
 c=FF(c,d,a,b,M6,17,0xa8304613)
 d=FF(b,c,d,a,M7,22,0xfd469501)
 a=FF(a,b,c,d,M8,7,0x698098d8)
 b=FF(d,a,b,c,M9,12,0x8b44f7af)
 c=FF(c,d,a,b,M10,17,0xffff5bb1)
 d=FF(b,c,d,a,M11,22,0x895cd7be)
 a=FF(a,b,c,d,M12,7,0x6b901122)
 b=FF(d,a,b,c,M13,12,0xfd987193)
 c=FF(c,d,a,b,M14,17,0xa679438e)
 d=FF(b,c,d,a,M15,22,0x49b40821)
 
第二輪
 a=GG(a,b,c,d,M1,5,0xf61e2562)
 b=GG(d,a,b,c,M6,9,0xc040b340)
 c=GG(c,d,a,b,M11,14,0x265e5a51)
 d=GG(b,c,d,a,M0,20,0xe9b6c7aa)
 a=GG(a,b,c,d,M5,5,0xd62f105d)
 b=GG(d,a,b,c,M10,9,0x02441453)
 c=GG(c,d,a,b,M15,14,0xd8a1e681)
 d=GG(b,c,d,a,M4,20,0xe7d3fbc8)
 a=GG(a,b,c,d,M9,5,0x21e1cde6)
 b=GG(d,a,b,c,M14,9,0xc33707d6)
 c=GG(c,d,a,b,M3,14,0xf4d50d87)
 d=GG(b,c,d,a,M8,20,0x455a14ed)
 a=GG(a,b,c,d,M13,5,0xa9e3e905)
 b=GG(d,a,b,c,M2,9,0xfcefa3f8)
 c=GG(c,d,a,b,M7,14,0x676f02d9)
 d=GG(b,c,d,a,M12,20,0x8d2a4c8a)
 
第三輪
 a=HH(a,b,c,d,M5,4,0xfffa3942)
 b=HH(d,a,b,c,M8,11,0x8771f681)
 c=HH(c,d,a,b,M11,16,0x6d9d6122)
 d=HH(b,c,d,a,M14,23,0xfde5380c)
 a=HH(a,b,c,d,M1,4,0xa4beea44)
 b=HH(d,a,b,c,M4,11,0x4bdecfa9)
 c=HH(c,d,a,b,M7,16,0xf6bb4b60)
 d=HH(b,c,d,a,M10,23,0xbebfbc70)
 a=HH(a,b,c,d,M13,4,0x289b7ec6)
 b=HH(d,a,b,c,M0,11,0xeaa127fa)
 c=HH(c,d,a,b,M3,16,0xd4ef3085)
 d=HH(b,c,d,a,M6,23,0x04881d05)
 a=HH(a,b,c,d,M9,4,0xd9d4d039)
 b=HH(d,a,b,c,M12,11,0xe6db99e5)
 c=HH(c,d,a,b,M15,16,0x1fa27cf8)
 d=HH(b,c,d,a,M2,23,0xc4ac5665)
 
第四輪
 a=II(a,b,c,d,M0,6,0xf4292244)
 b=II(d,a,b,c,M7,10,0x432aff97)
 c=II(c,d,a,b,M14,15,0xab9423a7)
 d=II(b,c,d,a,M5,21,0xfc93a039)
 a=II(a,b,c,d,M12,6,0x655b59c3)
 b=II(d,a,b,c,M3,10,0x8f0ccc92)
 c=II(c,d,a,b,M10,15,0xffeff47d)
 d=II(b,c,d,a,M1,21,0x85845dd1)
 a=II(a,b,c,d,M8,6,0x6fa87e4f)
 b=II(d,a,b,c,M15,10,0xfe2ce6e0)
 c=II(c,d,a,b,M6,15,0xa3014314)
 d=II(b,c,d,a,M13,21,0x4e0811a1)
 a=II(a,b,c,d,M4,6,0xf7537e82)
 b=II(d,a,b,c,M11,10,0xbd3af235)
 c=II(c,d,a,b,M2,15,0x2ad7d2bb)
 d=II(b,c,d,a,M9,21,0xeb86d391)

MD5為什么不可逆

MD5不可逆的原因,從原理上來看,

  • 第一是他使用了散列函數(shù),即上面的FGHI函數(shù)。
  • 第二是他在里面用了大量的移位操作,即<<<,這些是不可逆的

比如有10110011,我們左移三位,變成了10011000,高三位的101被頂了,低三位用0代替了,那此時就絕對不可能用10011000再逆向得到10110011了。

java實(shí)現(xiàn)和使用

public class MD5Util {
    public static void main(String[] args) throws IOException {
        System.out.println(encodeString("123"));
    }
    public static String encodeString(String plainText) throws UnsupportedEncodingException {
        return encodeBytes(plainText.getBytes("UTF-8"));
    }
    public static String encodeBytes(byte[] bytes) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(bytes);
            byte b[] = md.digest();
            int i;
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • Java抽象類和接口使用梳理

    Java抽象類和接口使用梳理

    對于面向?qū)ο缶幊虂碚f,抽象是它的一大特征之一,在?Java?中可以通過兩種形式來體現(xiàn)OOP的抽象:接口和抽象類,下面這篇文章主要給大家介紹了關(guān)于Java入門基礎(chǔ)之抽象類與接口的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • Java下界通配符(? super Type)的使用

    Java下界通配符(? super Type)的使用

    在Java中,? super Type是一個下界通配符,本文主要介紹了Java下界通配符(? super Type)的使用,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • Java?Main?函數(shù)啟動不退出的解決方案

    Java?Main?函數(shù)啟動不退出的解決方案

    這篇文章主要介紹了Java?Main?函數(shù)啟動不退出的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • Java中實(shí)現(xiàn)String.padLeft和String.padRight的示例

    Java中實(shí)現(xiàn)String.padLeft和String.padRight的示例

    本篇文章主要介紹了Java中實(shí)現(xiàn)String.padLeft和String.padRight,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Java設(shè)計模式之策略模式示例詳解

    Java設(shè)計模式之策略模式示例詳解

    策略模式屬于Java?23種設(shè)計模式中行為模式之一,該模式定義了一系列算法,并將每個算法封裝起來,使它們可以相互替換,且算法的變化不會影響使用算法的客戶。本文將通過示例詳細(xì)講解這一模式,需要的可以參考一下
    2022-08-08
  • java中如何獲取時間戳的方法實(shí)例

    java中如何獲取時間戳的方法實(shí)例

    時間戳通常是一個字符序列,唯一地標(biāo)識某一刻的時間,所以下面這篇文章主要給大家介紹了關(guān)于java中如何獲取時間戳的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • java實(shí)現(xiàn)實(shí)時通信聊天程序

    java實(shí)現(xiàn)實(shí)時通信聊天程序

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)實(shí)時通信聊天程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Java 對象序列化 NIO NIO2詳細(xì)介紹及解析

    Java 對象序列化 NIO NIO2詳細(xì)介紹及解析

    這篇文章主要介紹了Java 對象序列化 NIO NIO2詳細(xì)介紹及解析的相關(guān)資料,序列化機(jī)制可以使對象可以脫離程序的運(yùn)行而對立存在,需要的朋友可以參考下
    2017-02-02
  • Java環(huán)境配置圖文教程(推薦)

    Java環(huán)境配置圖文教程(推薦)

    下面小編就為大家?guī)硪黄狫ava環(huán)境配置圖文教程(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 詳解RocketMQ中的消費(fèi)者啟動與消費(fèi)流程分析

    詳解RocketMQ中的消費(fèi)者啟動與消費(fèi)流程分析

    本文主要介紹了RocketMQ的消費(fèi)者啟動流程,結(jié)合官方源碼和示例,一步步講述消費(fèi)者在啟動和消息消費(fèi)中的的工作原理及內(nèi)容,并結(jié)合平時業(yè)務(wù)工作中,對我們所熟悉的順序、push/pull模式等進(jìn)行詳細(xì)分析,以及對于消息消費(fèi)失敗和重投帶來問題去進(jìn)行分析,需要的朋友可以參考下
    2022-07-07

最新評論