我实现的一个MD5代码,C/C++版本

来源:互联网 发布:linux主机监控 编辑:程序博客网 时间:2024/05/21 18:47
#ifndef YMD5_H_#define YMD5_H_#include <string>using std::string;namespace yyy {typedef unsigned int uint32;class MD5 {public:  static string Md5(const string& s);  static char*  Md5(char* r, const char* s);private://对数组做填充  static size_t AppendString(char* buf, size_t textlen);//四轮处理  static void FourRoundRun(uint32 res[], const char* buf);//数组中的每个gn[i][j]元素通过公式: 2 * sin(16* 1) 32 i + j + 计算后取整得到  static uint32 gn[4][16];//做循环移位的步数    static int move[4][16];};}#endif
#include "YMd5.h"#include <iostream>#include <stdio.h>#include <string.h>using namespace std;namespace yyy {//四个逻辑函数,用函数指针数组组织static inline uint32 F(uint32 x, uint32 y, uint32 z) { return (x&y)|((~x)&z);}static inline uint32 G(uint32 x, uint32 y, uint32 z) { return (x&z)|(y&(~z));}static inline uint32 H(uint32 x, uint32 y, uint32 z) { return x^y^z;}static inline uint32 I(uint32 x, uint32 y, uint32 z) { return y^(x|(~z));}typedef uint32 (*P_FUN)(uint32 x, uint32 y, uint32 z);P_FUN pfun[4] = {F, G, H, I};//将整数x循环左移n位static inline uint32 CirLeftMove(uint32 x, int n) { return (x<<n)|((x&0xffffffff)>>(32-n)); }//将buf从start开始的offset个字节内存赋值到a这个uint数组,要求a的长度是offset/4(向上取整)static inline void Char2Uint(uint32 a[], const char* buf, const int len) { memcpy(a, buf, len); }//将a从start开始的offset个整数内存赋值到buf这个字符串,要求buf的长度是4*offsetstatic inline char* Uint2Char(char* buf, const uint32 a[], const int offset) { memcpy(buf, a, offset*4); }//将a数组,按16进制输出成字符串数组,输入buf长度大于32+1,函数里面不作检查static const char int2hex[17] = {'0', '1', '2', '3', '4', '5', '6', '7',    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};static inline char* Uint2HexString(char* buf, const uint32 a[], const int len) {  int i = -1;  for (int j = 0; j < len; ++j) {    buf[++i] = int2hex[(a[j] >>  4) & 0xf];    buf[++i] = int2hex[(a[j] >>  0) & 0xf];    buf[++i] = int2hex[(a[j] >> 12) & 0xf];    buf[++i] = int2hex[(a[j] >>  8) & 0xf];    buf[++i] = int2hex[(a[j] >> 20) & 0xf];    buf[++i] = int2hex[(a[j] >> 16) & 0xf];    buf[++i] = int2hex[(a[j] >> 28) & 0xf];    buf[++i] = int2hex[(a[j] >> 24) & 0xf];  }  buf[++i] = 0;  return buf;}int MD5::move[4][16] = {  { 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 }};uint32 MD5::gn[4][16] = {  { 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 }};#define J_TO_I(i, j) {\  if (r == 0) i = j & 0xf; \  else if (r == 1) i = (1+5*j) & 0xf; \  else if (r == 2) i = (5+3*j) & 0xf; \  else if (r == 3) i = (7*j) & 0xf; \}inline void MD5::FourRoundRun(uint32 res[], const char * buf) {  uint32 a[16];  Char2Uint(a, buf, 64);  uint32 tmp_res[4];  memcpy(tmp_res, res, sizeof(res)*4);  for(int r = 0; r < 4; ++r) {    for (int j = 0; j < 16; ++j) {      int i = 0;      J_TO_I(i, j);      tmp_res[0] = tmp_res[1] + CirLeftMove(tmp_res[0] + (*(pfun[r]))(tmp_res[1], tmp_res[2], tmp_res[3]) + a[i] + gn[r][j], move[r][j]);      int tmp = tmp_res[3];      tmp_res[3] = tmp_res[2];      tmp_res[2] = tmp_res[1];      tmp_res[1] = tmp_res[0];      tmp_res[0] = tmp;    }  }  res[0] += tmp_res[0];  res[1] += tmp_res[1];  res[2] += tmp_res[2];  res[3] += tmp_res[3];}char* MD5::Md5(char* r, const char* s) {  uint32 temp[4], result[4] = { 0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476 };  const size_t BUFLEN = 64;  char buf[BUFLEN*2+1];  size_t offset = 0, len = 0;  memcpy(temp, result, sizeof(result));  bool end = false;  while (!end) {    strncpy(buf, s+offset, BUFLEN);    buf[BUFLEN] = 0;    len = strlen(buf);    offset += len;    if (len < BUFLEN) {      len = AppendString(buf, strlen(s));      end = true;    }    if (len == 64) {      FourRoundRun(result, buf);     } else if (len == 128) {      FourRoundRun(result, buf);      FourRoundRun(result, buf+BUFLEN);    }  }  strcpy(r, Uint2HexString(buf, result, 4));  return r;}string MD5::Md5(const string& s) {  char res[33];  Md5(res, s.c_str());  return string(res);}inline size_t MD5::AppendString(char* buf, size_t textlen) { //这里必须保证使用的buf有(64*2+1)byte的长度  size_t append_len, retlen, len = strlen(buf);  size_t res = len&0x3f;  if (res >= 56) {    append_len = 64 - res + 56;    retlen = 128;  } else if (res < 56) {    append_len = 56 - res;    retlen = 64;  }   *(buf+len) = 0x80;  memset(buf+len+1, 0, append_len-1);  textlen *= 8;//转换成bit长度  memcpy(buf+len+append_len, &textlen, sizeof(size_t));  return retlen;}}


原创粉丝点击