文章目录
1 算法原理概述
MD5,即Message-Digest Algorithm 5 (信息-摘要算法5),是广泛使用的Hash 算法,用于确保信息传输的完整性和一致性。 MD5 使用little-endian(小端模式),输入任意不定长度信息,以 512-bit 进行分组,生成四个32-bit 数据,最后联合输出固定 128-bit 的信息摘要。 其基本过程为:填充、分块、缓冲区初始化、循环压缩、得出结果。
基本流程图如下:
2 总体结构
- MD5.hpp:定义MD5类,宏定义4轮循环中使用的生成函数,以及循环移位
- MD5.cpp:实现MD5.hpp中定义的类方法
- main.cpp:测试文件,数据来自https://www.ietf.org/rfc/rfc1321.txt
3 模块分解
3.1 填充及分块模块
3.2 初始化模块
3.3 循环压缩模块
3.4 整数转字符串模块
3.5 获取MD5模块(总)
3.6 输入模块
3.7 输出模块
4 数据结构
4.1 MD5类
面向对象编程,在类内定义各个变量和函数,可以使架构更加清晰。
4.2 unsigned int
unsigned int为32-bit无符号整数,正好可以对应一个32-bit分组。
5 编译运行结果
使用了RCF 1321中给出的标准测试样例进行测试:
6 源代码
MD5.hpp
// MD5.hpp
#include <iostream>
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
typedef unsigned int byte4;
typedef unsigned long long int byte8;
using namespace std;
class MD5{
public:
MD5(const string &input);
void padding();
void init();
void transform(byte8 blockNum);
string toString(byte4 a);
string getMD5();
private:
string input; // 输入字符串消息
byte4* M; // 填充后的用32-bit整数数组表示的32-bit分组
byte8 L; // L个512-bit(即64-byte)分组
byte4 A, B, C, D; // MD 缓冲区,4个32-bit 寄存器(A, B, C, D)
};
MD5.cpp
// MD5.cpp
# include "MD5.hpp"
// 各次迭代运算采用的T值, T[i] = int((2^32)*|sin(i)|)
const byte4 T[]={
0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
0x6b901122,0xfd987193,0xa679438e,0x49b40821,
0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
0xfffa3942,0x8771f681,<