MD5 算法流程
先通过下面的命令对 md5
算法有个感性的认识:
$ md5sum /tmp/1.txt
1dc792fcaf345a07b10248a387cc2718 /tmp/1.txt$ md5sum // 从键盘输入,ctrl-d 结束输入
hello, world!
910c8bc73110b0cd1bc5d2bcae782511 -
从上面可以看到,一个文件或一段数据的 md5
值是一个字符串,这个字符串一共有 32
个字符,每个字符都是一个十六进制字符。因此,如果每 8
个字符一组的话,可以分为 4
组。同时,每 8
个字符可以看成一个 4
字节整数的十六进制表示。所以,md5
值是 4
个 4
字节整数的十六进制表示。
有了这样的认识,可能大概已经猜到,md5
其实是通过某种运算将任意长度的数据转换为 4
个 4
字节整数。
这 4
个 4
字节整数在 md5
里面叫作链接变量(或者叫作状态),可以用 A
, B
, C
, D
表示,在初始时,这 4
个变量的取值是:
A = 0x01234567
B = 0x89abcdef
C = 0xfedcba98
D = 0x76543210
现在先暂停一下,来关注数据长度的问题。 按照要求,md5
算法是以 64
字节分组为单位来处理输入文本的,因此当数据长度不是 64
字节整数倍的时候,需要在数据的末尾进行填充,使其长度为 64
字节的整数倍。填充的方法是先在数据的末尾添加一个 bit
的 1
,再接若干个 bit
的 0
,然后再附加上一个 64 bit
的数,这个数的取值是填充前数据的长度。
至此,在经过填充(如果需要填充的话)后,md5
算法处理的数据长度一定是 64
字节的整数倍。接下来,就进入了算法的主循环,循环的次数是数据中 64
字节分组的数目。
在每次循环之前,需要将 A
, B
, C
,D
这 4
个变量复制到另外的 4
个变量中,即:A
到 a
、B
到 b
、C
到 c
、D
到 d
,在每次循环中,计算操作是在a
,b
,c
,d
这 4
个变量上进行的,计算完后还需要将 a
,b
,c
,d
加回到原来的A
,B
,C
,D
上,以便进行下一次循环,由此可见 md5
算法是存在较长的数据依赖的,不太好用向量进行优化。
每次循环有 4
轮计算,每一轮进行 16
次运算,这里的运算比较复杂,后面用宏定义进行表示。
具体来说,每次循环有 64
次运算,第一轮包含第 1
到 16
次运算,使用的宏是 FF()
,第二轮包含第 17
到 32
次运算,使用的宏是 GG()
,第三轮包含第 33
到 48
次运算,使用的宏是 HH()
,第四轮包含第 49
到 64
次运算,使用的宏是 II()
。
这 4
个宏的定义分别是:
1)FF()
:
FF(a, b, c, d, Mj, s, ti) 表示 a = b + ((a + F(b, c, d) +Mj + ti) <<< s)
其中
F(X, Y, Z) = (X & Y) | ((~X) & Z)
2)GG()
:
GG(a, b, c, d, Mj, s, ti) 表示 a = b + ((a + G(b, c, d) +Mj + ti) <<< s)
其中
G(X, Y, Z) = (X & Z) | (Y & (~Z))
3)HH
:
HH(a, b, c, d, Mj, s, ti) 表示 a = b + ((a + H(b, c, d) +Mj + ti) <<< s)
其中
H(X, Y, Z) = X ^ Y ^ Z
4)II()
:
II(a, b, c, d, Mj, s, ti) 表示 a = b + ((a + I(b, c, d) +Mj + ti) <<< s)
其中
I(X, Y, Z) = Y ^ (X | (~Z))
上述宏定义中的 a
,b
,c
,d
之前已提到,这里不再解释,Mj
是 64
字节分组中第 j
个 4
字节整数( 0<=j<=15
),ti
是常量,<<<
是循环左移, s
也是常量。
下面具体罗列出这 64
次运算的表达式,其中 x[j]
为数据分组的第 j
个 4
字节整数:
// 第一轮FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */FF (c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */FF (c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */FF (b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */FF (a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */FF (c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */FF (b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */FF (a, b, c, d, x[12], 7, 0x6b901122); /* 13 */FF (d, a, b, c, x[13], 12, 0xfd987193); /* 14 */FF (c, d, a, b, x[14], 17, 0xa679438e); /* 15 */FF (b, c, d, a, x[15], 22, 0x49b40821); /* 16 */// 第二轮
GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */GG (d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */GG (c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */GG (d, a, b, c, x[10], 9, 0x2441453); /* 22 */GG (c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */GG (d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */GG (a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */// 第三轮
HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */HH (d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */HH (c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */HH (b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */HH (b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */HH (a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */HH (b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */HH (d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */// 第四轮
II (a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */II (d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */II (c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */II (b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */II (a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */II (c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */II (b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */II (c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */II (b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */II (a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */II (d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */II (b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
在每次循环中,当执行完上述 64
次运算后,还要将最后得到的 a
, b
, c
, d
分别加回到原来的 A
, B
, C
, D
中,即:
A += a;B += b;C += c;D += d;
这样在经过一次循环后,A
, B
, C
,D
都被更新了,然后进行下一次循环,直到处理完所有的 64
字节分组。
最后的输出是 A
、B
、C
、D
这 4
个 4
字节变量的十六进制,也即数据的 md5
值,但值得注意的是输出的字符串是 A
,B
, C
, D
这 4
个变量的小端序 16
进制表示。
参考资料:
1.md5
算法的 RFC
:rfc1321
相关文章:
MD5 算法流程
先通过下面的命令对 md5算法有个感性的认识: $ md5sum /tmp/1.txt 1dc792fcaf345a07b10248a387cc2718 /tmp/1.txt$ md5sum // 从键盘输入,ctrl-d 结束输入 hello, world! 910c8bc73110b0cd1bc5d2bcae782511 -从上面可以看到,一个文件或一…...

TCP/IP协议详解
TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/互联网协议)是互联网的基本协议,也是国际互联网络的基础。 TCP/IP 不是指一个协议,也不是 TCP 和 IP 这两个协议的合称,而是一个协…...

SSM SpringBoot vue快递柜管理系统
SSM SpringBoot vue快递柜管理系统 系统功能 登录 注册 个人中心 快递员管理 用户信息管理 用户寄件管理 配送信息管理 寄存信息管理 开发环境和技术 开发语言:Java 使用框架: SSM(Spring SpringMVC Mybaits)或SpringBoot 前端: vue 数据库:Mys…...

期权交易保证金比例一般是多少?
期权交易是一种非常受欢迎的投资方式之一,它为期权市场带来了更为多样化和灵活化的交易形式。而其中的期权卖方保证金比例是期权交易中的一个重要指标,直接关系到投资者的风险与收益,下文介绍期权交易保证金比例一般是多少?本文来…...

029:vue项目,勾选后今天不再弹窗提示
第029个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下,本专栏提供行之有效的源代码示例和信息点介绍,做到灵活运用。 (1)提供vue2的一些基本操作:安装、引用,模板使…...
Unet语义分割-语义分割与实例分割概述-001
文章目录 前言1、图像分割和图像识别1.语义分割2.实例分割 2、分割任务中的目标函数定义3.IOU 前言 大纲目录 1、图像分割和图像识别 下面是图像识别和图像分割的区别,图像识别就是识别出来,画个框,右边的是图像分割。 1.语义分割 两张图把…...

Linux常用命令字典篇
Linux命令 1. 翻页查看文件 less [-N] 文件名:可以向后翻页,也可以向前翻页,-N表示显示行号 more 文件名:仅可以向后翻页 2. 端口占用信息查看 netstat -tunlp | grep 端口号:查看端口号对应的信息 lsof i: 端口号…...
__declspec(novtable) 在C++
__declspec(novtable) 在C中接口中广泛应用. 不容易看到它是因为在很多地方它都被定义成为了宏. 比如说ATL活动模板库中的ATL_NO_VTABLE, 其实就是__declspec(novtable). __declspec(novtable) 就是让类不要有虚函数表以及对虚函数表的初始化代码, 这样可以节省运行时间和空间.…...
ChatGPT充值,银行卡被拒绝
目录 前言步骤1. 魔法地址选择2. 选择手机号码(归属地)3. 勾选,服从协议4. 填写信息5. 完善账单地址6. 订阅成功 前言 大家好,今天我在订阅ChatGPT4时,遭遇了银行卡被拒绝的尴尬境地。这里有个技巧,我来给…...

算法通过村第七关-树(递归/二叉树遍历)白银笔记|递归实战
文章目录 前言1. 深入理解前中后序遍历从小到大递推分情况讨论,明确结束条件组合出完整的方法:从大到小 画图推演 总结 前言 提示:没有客观公正的记忆这回事,所有的记忆都是偏见,都是为自己的存活而重组过的经验。--国…...
抖音小程序开发教学系列(6)- 抖音小程序高级功能
第六章:抖音小程序高级功能 6.1 抖音小程序的支付功能6.1.1 接入流程6.1.2 注意事项 6.2 抖音小程序的地理位置和地图功能6.2.1 接入流程6.2.2 使用方法 6.3 抖音小程序的实时音视频功能6.3.1 接入流程6.3.2 使用方法 6.4 抖音小程序的小游戏开发6.4.1 基本流程6.4.…...

SpringBoot运行原理
目录 SpringBootApplication ComponentScan SpringBootConfiguration EnableAutoConfiguration 结论 SpringbootApplication(主入口) SpringBootApplication public class SpringbootConfigApplication {public static void main(String[] args) {…...

为什么Proteus串口无法正常显示
我以前就可以正常显示,但是最近一段时间,发现串口无法正常显示,试了很多办法都不行, 然后今天干好有点时间就刷了个机,然后居然就好了, 这就说明:Proteus不正常可能是病毒破坏了某个文件导致异…...

Furion api npm web vue混合开发
Furion api npm web vue混合开发 Furion-api项目获取swagger.json文件复制json制作ts包删除非.ts文件上传到npm获取npm包引用 Furion-api项目获取swagger.json文件 使用所有接口合并的配置文件 复制json制作ts包 https://editor.swagger.io 得到 typescript-axios-clien…...

【搭建私人图床】本地PHP搭建简单Imagewheel云图床,在外远程访问
文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测…...

BOM操作
文章目录 BOM事件页面加载调整窗口事件定时器停止计时器Location对象History对象Offsetleft获取元素偏移Offset与style的区别可视区client系列滚动scroll系列Mouseover和mousenter区别 动画原理实现动画封装给不同对象添加定时器缓动动画原理多个位置间移动 BOM事件 页面加载 …...

【校招VIP】前端操作系统之存储管理加密
考点介绍 加密算法有很多,如不可逆的摘要算法MD5、SHA(安全哈希算法),可逆的Base64编码,对称加密算法DES、AES,还有非对称加密算法DH、RSA等。那是不是说明我们可以使用任何一种加密算法就能保证网站的安全…...

windows 下载安装 mysql
windows 下载安装 mysql 官网地址:https://dev.mysql.com/ 下载地址:https://cdn.mysql.com//Downloads/MySQLInstaller/mysql-installer-community-8.0.34.0.msi 点击 Downloads 点击 MySQL Community (GPL) Downloads 点击 MySQL Installer for Window…...

第14章_瑞萨MCU零基础入门系列教程之QSPI
本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id728461040949 配套资料获取:https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总: ht…...

【pygame】01 pygame制作游戏的最小系统
这次使用sublimepython进行pygame的游戏开发,目的是学习使用python的基本操作和常用模块 添加一个文件夹到工程 最小系统 1.导入使用的模块 2.初始化:pygame.init函数包含了各个子模块的初始化,可以重复调用 3.pygame.display.set_mode返…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
flow_controllers
关键点: 流控制器类型: 同步(Sync):发布操作会阻塞,直到数据被确认发送。异步(Async):发布操作非阻塞,数据发送由后台线程处理。纯同步(PureSync…...
JS红宝书笔记 - 3.3 变量
要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...