MD5使用比较广泛,并不只局限于数据加密,它的概念这里就不介绍了,这里只谈谈MD5的代码实现。
MD5计算的算法是统一的,但实现如果实现时参数不一样,同样一段数据,不同的算法计算出的结果就不一样。为了保证MD5算法实现在不同的平台,不同的语言实现时计算结果一致,人们制定了RFC1321规范。比如java中MD5的算法实现就是遵循RFC1321规范的。我们知道C/C++并没有内置MD5计算的函数,所以在C++/C环境下要实现与java平台一样的MD5计算,就要自己实现。
RFC1321的官方网站提供了MD5的C语言实现。这是很权威的了。
但如果想要C++的版本,就要仔细挑选了。我们当然希望自己的MD5实现计算出来的结果与别的系统计算的结果一样,所以遵循RFC1321是必须的。网上也可以找到很多C++版本的实现。但哪一个遵循RFC1321规范的呢?
最近我就遇到了这个问题,经过实际测试,可以确认下面这个版本是没问题的,遵循RFC1321,与java平台下计算的结果一致。
http://www.zedwood.com/article/cpp-md5-function

为防止链接失效,下面贴出源码,代码已经在VS2015,CLang下编译通过,并在win64、android/arm平台上测试验证通过,另外我在使用过程对下面的原始代码中一些不合理的地方做了一些修改,修改后的代码参见码云仓库地址:https://gitee.com/l0km/common_source_cpp/tree/master/md5
调用示例参见: https://gitee.com/l0km/feature_se/blob/master/jni/BeanUtilits.cpp

md5.h

/* MD5converted to C++ class by Frank Thilo (thilo@unix-ag.org)for bzflag (http://www.bzflag.org)based on:md5.h and md5.creference implementation of RFC 1321Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.These notices must be retained in any copies of any part of this
documentation and/or software.*/#ifndef BZF_MD5_H
#define BZF_MD5_H#include <cstring>
#include <iostream>// a small class for calculating MD5 hashes of strings or byte arrays
// it is not meant to be fast or secure
//
// usage: 1) feed it blocks of uchars with update()
//      2) finalize()
//      3) get hexdigest() string
//      or
//      MD5(std::string).hexdigest()
//
// assumes that char is 8 bit and int is 32 bit
class MD5
{public:typedef unsigned int size_type; // must be 32bitMD5();MD5(const std::string& text);void update(const unsigned char *buf, size_type length);void update(const char *buf, size_type length);MD5& finalize();std::string hexdigest() const;friend std::ostream& operator<<(std::ostream&, MD5 md5);private:void init();typedef unsigned char uint1; //  8bittypedef unsigned int uint4;  // 32bitenum {blocksize = 64}; // VC6 won't eat a const static int herevoid transform(const uint1 block[blocksize]);static void decode(uint4 output[], const uint1 input[], size_type len);static void encode(uint1 output[], const uint4 input[], size_type len);bool finalized;uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunkuint4 count[2];   // 64bit counter for number of bits (lo, hi)uint4 state[4];   // digest so faruint1 digest[16]; // the result// low level logic operationsstatic inline uint4 F(uint4 x, uint4 y, uint4 z);static inline uint4 G(uint4 x, uint4 y, uint4 z);static inline uint4 H(uint4 x, uint4 y, uint4 z);static inline uint4 I(uint4 x, uint4 y, uint4 z);static inline uint4 rotate_left(uint4 x, int n);static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);
};std::string md5(const std::string str);#endif

md5.cpp

/* MD5converted to C++ class by Frank Thilo (thilo@unix-ag.org)for bzflag (http://www.bzflag.org)based on:md5.h and md5.creference implemantion of RFC 1321Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.These notices must be retained in any copies of any part of this
documentation and/or software.*//* interface header */
#include "md5.h"/* system implementation headers */
#include <cstdio>// Constants for MD5Transform routine.
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21///// F, G, H and I are basic MD5 functions.
inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {return x&y | ~x&z;
}inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {return x&z | y&~z;
}inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {return x^y^z;
}inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {return y ^ (x | ~z);
}// rotate_left rotates x left n bits.
inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {return (x << n) | (x >> (32-n));
}// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
// Rotation is separate from addition to prevent recomputation.
inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
}inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
}inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
}inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
}//// default ctor, just initailize
MD5::MD5()
{init();
}//// nifty shortcut ctor, compute MD5 for string and finalize it right away
MD5::MD5(const std::string &text)
{init();update(text.c_str(), text.length());finalize();
}//void MD5::init()
{finalized=false;count[0] = 0;count[1] = 0;// load magic initialization constants.state[0] = 0x67452301;state[1] = 0xefcdab89;state[2] = 0x98badcfe;state[3] = 0x10325476;
}//// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
void MD5::decode(uint4 output[], const uint1 input[], size_type len)
{for (unsigned int i = 0, j = 0; j < len; i++, j += 4)output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
}//// encodes input (uint4) into output (unsigned char). Assumes len is
// a multiple of 4.
void MD5::encode(uint1 output[], const uint4 input[], size_type len)
{for (size_type i = 0, j = 0; j < len; i++, j += 4) {output[j] = input[i] & 0xff;output[j+1] = (input[i] >> 8) & 0xff;output[j+2] = (input[i] >> 16) & 0xff;output[j+3] = (input[i] >> 24) & 0xff;}
}//// apply MD5 algo on a block
void MD5::transform(const uint1 block[blocksize])
{uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];decode (x, block, blocksize);/* Round 1 */FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 *//* Round 2 */GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 *//* Round 3 */HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 *//* Round 4 */II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */state[0] += a;state[1] += b;state[2] += c;state[3] += d;// Zeroize sensitive information.memset(x, 0, sizeof x);
}//// MD5 block update operation. Continues an MD5 message-digest
// operation, processing another message block
void MD5::update(const unsigned char input[], size_type length)
{// compute number of bytes mod 64size_type index = count[0] / 8 % blocksize;// Update number of bitsif ((count[0] += (length << 3)) < (length << 3))count[1]++;count[1] += (length >> 29);// number of bytes we need to fill in buffersize_type firstpart = 64 - index;size_type i;// transform as many times as possible.if (length >= firstpart){// fill buffer first, transformmemcpy(&buffer[index], input, firstpart);transform(buffer);// transform chunks of blocksize (64 bytes)for (i = firstpart; i + blocksize <= length; i += blocksize)transform(&input[i]);index = 0;}elsei = 0;// buffer remaining inputmemcpy(&buffer[index], &input[i], length-i);
}//// for convenience provide a verson with signed char
void MD5::update(const char input[], size_type length)
{update((const unsigned char*)input, length);
}//// MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context.
MD5& MD5::finalize()
{static unsigned char padding[64] = {0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};if (!finalized) {// Save number of bitsunsigned char bits[8];encode(bits, count, 8);// pad out to 56 mod 64.size_type index = count[0] / 8 % 64;size_type padLen = (index < 56) ? (56 - index) : (120 - index);update(padding, padLen);// Append length (before padding)update(bits, 8);// Store state in digestencode(digest, state, 16);// Zeroize sensitive information.memset(buffer, 0, sizeof buffer);memset(count, 0, sizeof count);finalized=true;}return *this;
}//// return hex representation of digest as string
std::string MD5::hexdigest() const
{if (!finalized)return "";char buf[33];for (int i=0; i<16; i++)sprintf(buf+i*2, "%02x", digest[i]);buf[32]=0;return std::string(buf);
}//std::ostream& operator<<(std::ostream& out, MD5 md5)
{return out << md5.hexdigest();
}//std::string md5(const std::string str)
{MD5 md5 = MD5(str);return md5.hexdigest();
}

测试代码
main.cpp

#include <iostream>
#include "md5.h"using std::cout; using std::endl;int main(int argc, char *argv[])
{cout << "md5 of 'grape': " << md5("grape") << endl;return 0;
}

C++:符合RFC1321规范的MD5计算C++实现相关推荐

  1. 基于流式的md5计算-多线程下载工具Lwget介绍

    在数据传输的时候,我们希望实现以下目标: 1. 使用多线程传输,加速下载速度 2. 数据在传输过程中,进行流式md5计算,避免在传输完毕之后校验大文件 3. 支持断点续传 4. 支持http协议和ft ...

  2. 如何在命令行上创建符合特定规范的密码?

    在命令行上创建符合特定规范的密码.大多数网站或应用都要求用户创建带有安全密码的账户,以便他们能够迎合用户体验.虽然这有利于网站开发者,但肯定不会让用户的生活更轻松. 有时,创建密码的规则是如此严格,以 ...

  3. MD5计算,一个扩展类,哪里都能用

    最近有同学问到如何计算一个字节数组的MD5值,现在分享一个扩展类,有了它,MD5计算再也不用其他了. 先看示例: string s = "hello world";var s_md ...

  4. 一点关于MD5计算的封装

    本文参考:http://snowolf.iteye.com/blog/379860 MD5 是message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用 ...

  5. java go md5_Go语言中三种不同md5计算方式的性能比较

    前言 本文主要介绍的是三种不同的 md5 计算方式,其实区别是读文件的不同,也就是磁盘 I/O, 所以也可以举一反三用在网络 I/O 上.下面来一起看看吧. ReadFile 先看第一种, 简单粗暴: ...

  6. LWN:让内核支持符合FIPS规范的随机数!

    关注了就能看到更多这么棒的文章哦- FIPS-compliant random numbers for the kernel By Jake Edge December 7, 2021 DeepL a ...

  7. 文件Md5计算(C语言版)

    文件Md5计算(C语言版) 这是一个参考了网上很多人的C语言以及C++版本的计算工具而制作的,已对其优化了一部分,加了新功能:如果能计算出有效的Md5则自动复制到剪贴板,并且支持拖拽文件到窗口上,完全 ...

  8. 使用Go语言完成文件夹的MD5计算

    案例需求:我们的监测系统会定期的检查配置文件的变动,这些配置文件放置在一个独立的文件夹下面,我们可以通过对于整个的文件夹内所有文件进行md5的计算来完成监测,本文就通过Go语言实现了一个命令行工具,完 ...

  9. 大文件MD5计算 C语言 (从OpenSSL库中分离算法:三)

    从OpenSSL库中分离算法-MD5算法-大文件MD5计算 续上述博客 小文件计算MD5时,可以把文件数据一次性都读到内存中计算,但当文件很大时,将文件一次性读到内存中是不可行的,此时,需要对文件数据 ...

最新文章

  1. 【转】流言终结者:Windows系统与Linux系统之间的8个流言
  2. 【基带传输】基于matlab的简易无线基带传输系统的仿真
  3. 2022-03-09
  4. OpenMP和MPI的区别
  5. Druid 数据源连接池配置
  6. 关于SQLserver 的windows验证
  7. 【渝粤教育】 国家开放大学2020年春季 1050金融理论前沿课题 参考试题
  8. 牛津教授吐槽DeepMind心智神经网络,还推荐了这些多智能体学习论文
  9. 查找在Git中删除文件的时间
  10. 容器技术Docker K8s 50 容器镜像服务(ACR)详解-使用与实践
  11. Fiddler中文使用教程-AutoResponder
  12. java中的杨辉三角形_Java编写杨辉三角
  13. 专利局文件如何删除后面的注意事项
  14. RGMII以太网测试方案
  15. 4399游戏Web前端工程师2021秋招面经
  16. python编写自定义函数print_triangle(n)_Python 实验8 函数(1).doc
  17. 软考考前必看之热门问题详解
  18. android 视频相册,安卓11版本保存视频到相册,提示保存成功,相册里没有视频...
  19. 你所不知道的C盘变大的原因
  20. H3C S7500E系列高端多业务路由交换机

热门文章

  1. android+实现微信对话框样式,实现微信对话框的图片样式以及图片边框
  2. 新加硬盘但计算机里找不着,win10新加的硬盘为什么不显示_win10新加的硬盘不显示恢复方法-win7之家...
  3. 从编程小白到入门码农的五个途径
  4. 眼科赛道的“觉醒年代”,清晰医疗赴港能否具备后发优势?
  5. 读取pb模型进行预测
  6. oracle lms进程 内存,lms进程耗用大量内存
  7. 专业计算机和游戏计算机配置要求,游戏直播电脑配置要求2019|游戏直播电脑配置单推荐(可装win7)...
  8. Linux 29岁啦!这29个重大事件你有必要了解一下
  9. 简明扼要阐述synchronized和lock的区别
  10. ARM芯片内部堆栈的理解及MAP文件的查看