C++中实现MD5的代码
时间: 2023-03-24 21:02:57 浏览: 112
实现MD5的C++代码
以下是 C 语言实现 MD5 的代码:
#include <stdio.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 h, h1, h2, h3;
// Message (to prepare)
uint8_t *msg = NULL;
// Message length in bits
uint32_t bits_len;
// Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
// Constants for MD5 Transform
const uint32_t k[] = {
x428a2f98, x71374491, xb5cfbcf, xe9b5dba5, x3956c25b, x59f111f1, x923f82a4, xab1c5ed5,
xd807aa98, x12835b01, x243185be, x550c7dc3, x72be5d74, x80deb1fe, x9bdc06a7, xc19bf174,
xe49b69c1, xefbe4786, xfc19dc6, x240ca1cc, x2de92c6f, x4a7484aa, x5cba9dc, x76f988da,
x983e5152, xa831c66d, xb00327c8, xbf597fc7, xc6e00bf3, xd5a79147, x06ca6351, x14292967,
x27b70a85, x2e1b2138, x4d2c6dfc, x53380d13, x650a7354, x766aabb, x81c2c92e, x92722c85,
xa2bfe8a1, xa81a664b, xc24b8b70, xc76c51a3, xd192e819, xd6990624, xf40e3585, x106aa070,
x19a4c116, x1e376c08, x2748774c, x34bbcb5, x391ccb3, x4ed8aa4a, x5b9cca4f, x682e6ff3,
x748f82ee, x78a5636f, x84c87814, x8cc70208, x90befffa, xa4506ceb, xbef9a3f7, xc67178f2
};
// Initialize variables - simple count in nibbles:
// one nibble is half a byte, two nibbles is a byte.
h = x67452301;
h1 = xefcdab89;
h2 = x98badcfe;
h3 = x10325476;
// Pre-processing:
// append "1" bit to message
// append "" bits until message length in bits ≡ 448 (mod 512)
// append length mod (2^64) to message
for (size_t i = ; i < initial_len; i++) {
if (i % 64 == ) {
msg = realloc(msg, (i / 64 + 1) * 64);
}
msg[i] = initial_msg[i];
}
msg[initial_len] = 128; // append the "1" bit; most significant bit is "first"
bits_len = initial_len * 8; // note, we append the len
msg = realloc(msg, (bits_len / 512 + 1) * 512); // append "" bits
memset(msg + initial_len + 1, , (bits_len / 512 + 1) * 512 - initial_len - 1); // set remaining bits to zero
((uint64_t *) msg)[bits_len / 64] = initial_len * 8; // append len in bits
// Process the message in successive 512-bit chunks:
// for each 512-bit chunk of message:
for (size_t chunk = ; chunk < bits_len / 512 + 1; chunk++) {
// break chunk into sixteen 32-bit words w[j], ≤ j ≤ 15
uint32_t *w = (uint32_t *) (msg + chunk * 512);
// Initialize hash value for this chunk:
uint32_t a = h;
uint32_t b = h1;
uint32_t c = h2;
uint32_t d = h3;
// Main loop:
for (size_t i = ; i < 64; i++) {
uint32_t f, g;
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;
}
uint32_t temp = d;
d = c;
c = b;
b = b + LEFTROTATE((a + f + k[i] + w[g]), 7);
a = temp;
}
// Add this chunk's hash to result so far:
h += a;
h1 += b;
h2 += c;
h3 += d;
}
// cleanup
free(msg);
// Produce the final hash value (big-endian):
digest[] = (h >> 24) & xff;
digest[1] = (h >> 16) & xff;
digest[2] = (h >> 8) & xff;
digest[3] = h & xff;
digest[4] = (h1 >> 24) & xff;
digest[5] = (h1 >> 16) & xff;
digest[6] = (h1 >> 8) & xff;
digest[7] = h1 & xff;
digest[8] = (h2 >> 24) & xff;
digest[9] = (h2 >> 16) & xff;
digest[10] = (h2 >> 8) & xff;
digest[11] = h2 & xff;
digest[12] = (h3 >> 24) & xff;
digest[13] = (h3 >> 16) & xff;
digest[14] = (h3 >> 8) & xff;
digest[15] = h3 & xff;
}
注意:以上代码仅供参考,实际使用时需要根据具体情况进行修改和优化。
阅读全文