C语言写一个MD5校验函数
时间: 2023-05-20 22:05:45 浏览: 166
C语言计算文件的MD5校验值
5星 · 资源好评率100%
以下是一个C语言的MD5校验函数的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
void md5(const uint8_t *initial_msg, size_t initial_len, uint8_t *digest) {
// These vars will contain the hash
uint32_t h0, h1, h2, h3;
// Message (to prepare)
uint8_t *msg = NULL;
// Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
// r specifies the per-round shift amounts
uint32_t r[] = { 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 };
// Use binary integer part of the sines of integers (in radians) as constants// Initialize variables:
uint32_t k[] = {
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
};
// Pre-processing:
// append "1" bit to message
// append "0" bits until message length in bits ≡ 448 (mod 512)
// append length mod (2^64) to message
// (Prepended "0" bits are represented by adding a whole extra block)
uint32_t initial_len_bits = initial_len * 8;
// compute number of bytes mod 64
uint32_t initial_len_mod64 = initial_len % 64;
// compute number of padding bytes
uint32_t padding_len = initial_len_mod64 < 56 ? 56 - initial_len_mod64 : 120 - initial_len_mod64;
// allocate array for message with padding and a 64-bit length block appended
uint32_t new_len = initial_len + padding_len + 8;
msg = (uint8_t *)malloc(new_len);
memcpy(msg, initial_msg, initial_len);
// append the "1" bit
msg[initial_len] = 0x80;
// append padding bytes
for (uint32_t i = initial_len + 1; i < new_len - 8; i++) {
msg[i] = 0x00;
}
// append length in bits
for (uint32_t i = 0; i < 8; i++) {
msg[new_len - 8 + i] = (uint8_t)(initial_len_bits >> (i * 8));
}
// Process the message in successive 512-bit chunks:
// for each 512-bit chunk of message:
// break chunk into sixteen 32-bit words w[i], 0 ≤ i ≤ 15
// Initialize hash value for this chunk:
// a = h0
// b = h1
// c = h2
// d = h3
// Main loop:
// for i from 0 to 63
// if 0 ≤ i ≤ 15 then
// f = (b and c) or ((not b) and d)
// g = i
// else if 16 ≤ i ≤ 31
// f = (d and b) or ((not d) and c)
// g = (5×i + 1) mod 16
// else if 32 ≤ i ≤ 47
// f = b xor c xor d
// g = (3×i + 5) mod 16
// else if 48 ≤ i ≤ 63
// f = c xor (b or (not d))
// g = (7×i) mod 16
// Be wary of the below definitions of a,b,c,d
// rotate left function definition
// Let [abcd k s i] denote the operation
// a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
// Do the following 16 operations in order:
// [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
// [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
// [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
// [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
// Perform the following 16 operations in order:
// [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
// [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
// [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
// [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
// Perform the following 16 operations in order:
// [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
// [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
// [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
// [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
// Perform the following 16 operations in order:
// [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
// [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
// [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
// [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
// Add this chunk's hash to result so far:
// h0 = h0 + a
// h1 = h1 + b
// h2 = h2 + c
// h3 = h3 + d
// cleanup
free(msg);
// Output hash (little endian):
for (uint32_t i = 0; i < 4; i++) {
digest[i] = (uint8_t)(h0 >> (i * 8));
digest[i + 4] = (uint8_t)(h1 >> (i * 8));
digest[i + 8] = (uint8_t)(h2 >> (i * 8));
digest[i + 12] = (uint8_t)(h3 >> (i * 8));
}
}
int main(int argc, char **argv) {
uint8_t digest[16];
char *msg = "hello world";
md5((uint8_t *)msg, strlen(msg), digest);
for (int i = 0; i < 16; i++) {
printf("%02x", digest[i]);
}
printf("\n");
return 0;
}
```
阅读全文