c语言md5 哈希算法
时间: 2023-08-28 18:07:50 浏览: 80
C语言MD5算法STM32单片机亲测可用
下面是一个使用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_hash(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;
// Message length in bits
size_t new_len, offset;
uint32_t w[16];
uint32_t a, b, c, d, i, f, g, temp;
// Initialize variables
h0 = 0x67452301;
h1 = 0xEFCDAB89;
h2 = 0x98BADCFE;
h3 = 0x10325476;
// 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
for (new_len = initial_len + 1; new_len % (512 / 8) != 448 / 8; new_len++) {}
msg = (uint8_t *)calloc(new_len + 8, 1);
memcpy(msg, initial_msg, initial_len);
msg[initial_len] = 0x80; // append the "1" bit; most significant bit is "first"
offset = new_len / 8;
msg[offset++] = 0x80; // append the "1" bit; most significant bit is "first"
// append length in bits mod 2^64 to message
uint64_t bits_len = 8 * initial_len;
memcpy(msg + offset, &bits_len, sizeof(bits_len));
// Process the message in successive 512-bit chunks
// for each chunk
for (offset = 0; offset < new_len; offset += (512 / 8)) {
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
for (i = 0; i < 16; i++) {
w[i] = ((uint32_t)msg[offset + i * 4 + 0]) |
(((uint32_t)msg[offset + i * 4 + 1]) << 8) |
(((uint32_t)msg[offset + i * 4 + 2]) << 16) |
(((uint32_t)msg[offset + i * 4 + 3]) << 24);
}
// Initialize hash value for this chunk:
a = h0;
b = h1;
c = h2;
d = h3;
// Main loop:
for (i = 0; i < 64; i++) {
if (i < 16) {
f = (b & c) | ((~b) & d);
g = i;
} else if (i < 32) {
f = (d & b) | ((~d) & c);
g = (5 * i + 1) % 16;
} else if (i < 48) {
f = b ^ c ^ d;
g = (3 * i + 5) % 16;
} else {
f = c ^ (b | (~d));
g = (7 * i) % 16;
}
temp = d;
d = c;
c = b;
b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
a = temp;
}
// Add this chunk's hash to result so far:
h0 += a;
h1 += b;
h2 += c;
h3 += d;
}
// Cleanup
free(msg);
// Endianness conversion
digest[0] = (h0 >> 0) & 0xff;
digest[1] = (h0 >> 8) & 0xff;
digest[2] = (h0 >> 16) & 0xff;
digest[3] = (h0 >> 24) & 0xff;
digest[4] = (h1 >> 0) & 0xff;
digest[5] = (h1 >> 8) & 0xff;
digest[6] = (h1 >> 16) & 0xff;
digest[7] = (h1 >> 24) & 0xff;
digest[8] = (h2 >> 0) & 0xff;
digest[9] = (h2 >> 8) & 0xff;
digest[10] = (h2 >> 16) & 0xff;
digest[11] = (h2 >> 24) & 0xff;
digest[12] = (h3 >> 0) & 0xff;
digest[13] = (h3 >> 8) & 0xff;
digest[14] = (h3 >> 16) & 0xff;
digest[15] = (h3 >> 24) & 0xff;
}
int main(int argc, char *argv[]) {
uint8_t digest[16];
const char *msg = "hello world";
size_t len = strlen(msg);
md5_hash((const uint8_t *)msg, len, digest);
for (int i = 0; i < 16; ++i) {
printf("%02x", digest[i]);
}
printf("\n");
return 0;
}
```
注意,这段代码中的常量数组 `k` 和 `r` 分别对应 MD5 算法中的常量和循环移位位数,需要在代码中声明和初始化。
阅读全文