2026/3/10 14:47:13
网站建设
项目流程
网站服务器慢,怎么做免费个人网站,wordpress 新编辑器,个人网站流量怎么赚钱一#xff1a;概述 MD5算法是一种广泛使用的哈希函数#xff0c;可生成 128位哈希值。MD5 由Ronald Rivest于 1991 年设计#xff0c;用于取代早期的哈希函数MD4。MD5 算法是把任意长度的字节流 → 通过固定的非线性函数 位运算 → 压缩成 128 bit 状态。 MD5 可作为校验和…一概述MD5算法是一种广泛使用的哈希函数可生成 128位哈希值。MD5 由Ronald Rivest于 1991 年设计用于取代早期的哈希函数MD4。MD5 算法是把任意长度的字节流 → 通过固定的非线性函数 位运算 → 压缩成 128 bit 状态。MD5 可作为校验和算法用于验证数据完整性并检测意外的数据损坏。历史上它曾被广泛用作加密哈希函数但随后人们发现其存在多种安全漏洞。因此MD5 已不再适用于安全敏感场景。不过在非加密用途下MD5 仍然具有一定价值例如用于确定分区数据库中某个键所属的分区。由于其计算开销低于较新的安全哈希算法在对安全性要求不高的场合MD5 仍更受青睐。二算法原理MD5 是一种将任意长度消息映射为固定长度输出的哈希算法其输出长度为 128 位。算法首先将输入消息划分为若干个 512 位的数据块每个数据块由 16 个 32 位字组成。为满足分组处理的要求消息在处理前需要进行填充使其总长度成为 512 的整数倍。填充过程如下首先在消息末尾附加一个值为 1 的比特随后添加若干个值为 0 的比特使填充后的消息长度比 512 的倍数少 64 位最后用 64 位表示原始消息长度2的64次方取模并附加到消息末尾。MD5 的核心算法维护一个 128 位的内部状态该状态由四个 32 位字组成通常记为 A、B、C 和 D。这些状态变量在算法开始时被初始化为固定的常量。随后算法依次处理每一个 512 位消息块并在此过程中不断更新内部状态。每个消息块的处理过程由四个相似的阶段组成称为“轮”。每一轮包含 16 个基本操作这些操作基于非线性布尔函数、在 32 位无符号整数范围内进行加法运算溢出部分被丢弃循环左移运算则是在保持位数不变的情况下将移出的高位重新补回到低位。算法共定义了四种不同的非线性函数每一轮使用其中一种。三代码#include stdint.h #include string.h #include stdio.h /* MD5 四个非线性函数 */ #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)) static inline uint32_t rol(uint32_t x, uint32_t n) { return (x n) | (x (32 - n)); } /* 常量 */ static const uint32_t K[64] { 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,0x6d9d6122,0xfde5380c, 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70, 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05, 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665, 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039, 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1, 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1, 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 }; static const uint32_t S[64] { 7,12,17,22, 7,12,17,22, 7,12,17,22, 7,12,17,22, 5, 9,14,20, 5, 9,14,20, 5, 9,14,20, 5, 9,14,20, 4,11,16,23, 4,11,16,23, 4,11,16,23, 4,11,16,23, 6,10,15,21, 6,10,15,21, 6,10,15,21, 6,10,15,21 }; /* MD5 上下文 */ typedef struct { uint32_t state[4]; uint64_t bitlen; uint8_t buffer[64]; size_t buflen; } md5_ctx; /* 单个 512-bit 块处理 */ static void md5_process_block(md5_ctx* ctx, const uint8_t block[64]) { uint32_t A ctx-state[0]; uint32_t B ctx-state[1]; uint32_t C ctx-state[2]; uint32_t D ctx-state[3]; uint32_t M[16]; /* little-endian 解析 */ for (int i 0; i 16; i) { M[i] (uint32_t)block[i * 4] | ((uint32_t)block[i * 4 1] 8) | ((uint32_t)block[i * 4 2] 16) | ((uint32_t)block[i * 4 3] 24); } for (int i 0; i 64; i) { uint32_t Fv, g; if (i 16) { Fv F(B, C, D); g i; } else if (i 32) { Fv G(B, C, D); g (5 * i 1) % 16; } else if (i 48) { Fv H(B, C, D); g (3 * i 5) % 16; } else { Fv I(B, C, D); g (7 * i) % 16; } uint32_t tmp D; D C; C B; B B rol(A Fv K[i] M[g], S[i]); A tmp; } ctx-state[0] A; ctx-state[1] B; ctx-state[2] C; ctx-state[3] D; } /* 接口函数 */ void md5_init(md5_ctx* ctx) { ctx-state[0] 0x67452301; ctx-state[1] 0xefcdab89; ctx-state[2] 0x98badcfe; ctx-state[3] 0x10325476; ctx-bitlen 0; ctx-buflen 0; } void md5_update(md5_ctx* ctx, const uint8_t* data, size_t len) { ctx-bitlen (uint64_t)len * 8; while (len--) { ctx-buffer[ctx-buflen] *data; if (ctx-buflen 64) { md5_process_block(ctx, ctx-buffer); ctx-buflen 0; } } } void md5_final(md5_ctx* ctx, uint8_t out[16]) { size_t i ctx-buflen; ctx-buffer[i] 0x80; if (i 56) { memset(ctx-buffer i, 0, 64 - i); md5_process_block(ctx, ctx-buffer); i 0; } memset(ctx-buffer i, 0, 56 - i); for (int j 0; j 8; j) ctx-buffer[56 j] (ctx-bitlen (8 * j)) 0xff; md5_process_block(ctx, ctx-buffer); for (i 0; i 4; i) { out[i * 4 0] (ctx-state[i] 0) 0xff; out[i * 4 1] (ctx-state[i] 8) 0xff; out[i * 4 2] (ctx-state[i] 16) 0xff; out[i * 4 3] (ctx-state[i] 24) 0xff; } } /* 测试 */ int main(void) { const char* msg abc; uint8_t hash[16]; md5_ctx ctx; md5_init(ctx); md5_update(ctx, (const uint8_t*)msg, strlen(msg)); md5_final(ctx, hash); for (int i 0; i 16; i) printf(%02x, hash[i]); printf(\n); return 0; }