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返…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
