💖 简介
MD5加密算法,也叫信息摘要算法,在项目中经常用到,一直对其原理比较好奇,在学习nginx源码的过程中,发现有其实现,就单独拿出来,进行调试学习,对于理解其原理非常有帮助。
💖 算法代码
md5.h文件
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#ifndef _NGX_MD5_H_INCLUDED_
#define _NGX_MD5_H_INCLUDED_
#include <iostream>
#include <windows.h>
typedef struct {
uint64_t bytes;
uint32_t a, b, c, d;
u_char buffer[64];
} ngx_md5_t;
void ngx_md5_init(ngx_md5_t *ctx);
void ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size);
void ngx_md5_final(u_char result[16], ngx_md5_t *ctx);
#endif /* _NGX_MD5_H_INCLUDED_ */
md5.cpp
#include "md5.h"
#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)
#define ngx_memzero(buf, n) (void) memset(buf, 0, n)
#define ngx_memset(buf, c, n) (void) memset(buf, c, n)
static const u_char *ngx_md5_body(ngx_md5_t *ctx, const u_char *data,size_t size);
/*
md5初始化
*/
void
ngx_md5_init(ngx_md5_t *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->bytes = 0;
}
void
ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size)
{
size_t used, free;
used = (size_t)(ctx->bytes & 0x3f);
ctx->bytes += size;
if (used) {
free = 64 - used;
if (size < free) {
ngx_memcpy(&ctx->buffer[used], data, size);
return;
}
ngx_memcpy(&ctx->buffer[used], data, free);
data = (u_char *)data + free;
size -= free;
(void)ngx_md5_body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = ngx_md5_body(ctx, reinterpret_cast<const u_char*>(data), size & ~(size_t)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
void
ngx_md5_final(u_char result[16], ngx_md5_t *ctx)
{
size_t used, free;
used = (size_t)(ctx->bytes & 0x3f);
ctx->buffer[used++] = 0x80;
free = 64 - used;
if (free < 8) {
ngx_memzero(&ctx->buffer[used], free);
(void)ngx_md5_body(ctx, ctx->buffer, 64);
used = 0;
free = 64;
}
ngx_memzero(&ctx->buffer[used], free - 8);
ctx->bytes <<= 3;
ctx->buffer[56] = (u_char)ctx->bytes;
ctx->buffer[57] = (u_char)(ctx->bytes >> 8);
ctx->buffer[58] = (u_char)(ctx->bytes >> 16);
ctx->buffer[59] = (u_char)(ctx->bytes >> 24);
ctx->buffer[60] = (u_char)(ctx->bytes >> 32);
ctx->buffer[61] = (u_char)(ctx->bytes >> 40);
ctx->buffer[62] = (u_char)(ctx->bytes >> 48