c++实现md5加密的代码

最近发现md5加密算法挺有趣,特点是单向加密不可逆,加密后的字符串长度相等,于是就用C++尝试实现了一下

头文件定义

/*
*******************************************************
* brief: md5 encryption
* author: Monkey.Knight
*******************************************************
*/
#ifndef __MD5_ENCODE_H__
#define __MD5_ENCODE_H__
// std
#include <string>
// define
#define UInt32 unsigned int
#define BIT_OF_BYTE  8
#define BIT_OF_GROUP 512
#define SRC_DATA_LEN 64
// 四个非线性函数宏定义
#define DEF_F(X, Y, Z ) ((( (X) & (Y) )|((~X)&(Z))))
#define DEF_G(X, Y, Z)  (((X)&(Z))|((Y)&(~Z)))
#define DEF_H(X, Y, Z)  ((X)^(Y)^(Z))
#define DEF_I(X, Y, Z)  ((Y)^((X)|(~Z)))
// 求链接数函数宏定义
#define FF(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_F(b,c,d) + Mj + ti),s));
#define GG(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_G(b,c,d) + Mj + ti),s));
#define HH(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_H(b,c,d) + Mj + ti),s));
#define II(a, b, c, d, Mj, s, ti)  (a = b + CycleMoveLeft((a + DEF_I(b,c,d) + Mj + ti),s));
class Md5Encode {
public:
    // 4轮循环算法
    struct ParamDynamic{
        UInt32 ua_;
        UInt32 ub_;
        UInt32 uc_;
        UInt32 ud_;
        UInt32 va_last_;
        UInt32 vb_last_;
        UInt32 vc_last_;
        UInt32 vd_last_;
    };
public:
    Md5Encode() {
    }
    std::string Encode(std::string src_info);
protected:
    UInt32 CycleMoveLeft(UInt32 src_num, int bit_num_to_move);
    UInt32 FillData(const char *in_data_ptr, int data_byte_len, char** out_data_ptr);
    void RoundF(char *data_512_ptr, ParamDynamic & param);
    void RoundG(char *data_512_ptr, ParamDynamic & param);
    void RoundH(char *data_512_ptr, ParamDynamic & param);
    void RoundI(char *data_512_ptr, ParamDynamic & param);
    void RotationCalculate(char *data_512_ptr, ParamDynamic & param);
    std::string GetHexStr(unsigned int num_str);
private:
    // 幻数定义
    static const int kA;
    static const int kB;
    static const int kC;
    static const int kD;
    static const unsigned long long k_ti_num_integer;
};
#endif

源文件:

#include "md5_encode.h"
#include <iostream>
// 幻数定义
const int Md5Encode::kA = 0x67452301;
const int Md5Encode::kB = 0xefcdab89;
const int Md5Encode::kC = 0x98badcfe;
const int Md5Encode::kD = 0x10325476;
const unsigned long long Md5Encode::k_ti_num_integer = 4294967296;
// function: CycleMoveLeft
// @param src_num:要左移的数
// @param bit_num_to_move:要移动的bit位数
// @return  循环左移后的结果数
UInt32 Md5Encode::CycleMoveLeft(UInt32 src_num, int bit_num_to_move) {
    UInt32 src_num1 = src_num;
    UInt32 src_num2 = src_num;
    if (0 >= bit_num_to_move) {
        return src_num;
    }
    UInt32 num1 = src_num1 << bit_num_to_move;
    UInt32 num2 = src_num2 >> (32 - bit_num_to_move);

    return ((src_num1 << bit_num_to_move) \
        | (src_num2 >> (32 - bit_num_to_move)));
}
// function: FillData
// @param in_data_ptr:    要加密的信息数据
// @param data_byte_len: 数据的字节数
// @param out_data_ptr:  填充必要信息后的数据
// return : 填充信息后的数据长度,以字节为单位
UInt32 Md5Encode::FillData(const char *in_data_ptr, int data_byte_len, char** out_data_ptr) {
    int bit_num = data_byte_len*BIT_OF_BYTE;
    int grop_num = bit_num / BIT_OF_GROUP;
    int mod_bit_num = bit_num % BIT_OF_GROUP;
    int bit_need_fill = 0;
    if (mod_bit_num > (BIT_OF_GROUP - SRC_DATA_LEN)) {
        bit_need_fill = (BIT_OF_GROUP - mod_bit_num);
        bit_need_fill += (BIT_OF_GROUP - SRC_DATA_LEN);
    }
    else {
        bit_need_fill = (BIT_OF_GROUP - SRC_DATA_LEN) - mod_bit_num; //  这里多加了一个BIT_OF_GROUP,避免bit_need_fill正好等于0,暂时不加
    }
    int all_bit = bit_num + bit_need_fill;
    if (0 < bit_need_fill) {
        *out_data_ptr = new char[all_bit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE];
        memset(*out_data_ptr, 0, all_bit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
        // copy data
        memcpy(*out_data_ptr, in_data_ptr, data_byte_len);
        // fill rest data
        unsigned char *tmp = reinterpret_cast<unsigned char *>(*out_data_ptr);
        tmp += data_byte_len;
        // fill 1 and 0
        *tmp = 0x80;
        // fill origin data len
        unsigned long long * origin_num = (unsigned long long *)((*out_data_ptr) + ((all_bit / BIT_OF_BYTE)));
        *origin_num = data_byte_len*BIT_OF_BYTE;
    }
    return (all_bit / BIT_OF_BYTE + SRC_DATA_LEN / BIT_OF_BYTE);
}
void Md5Encode::RoundF(char *data_BIT_OF_GROUP_ptr, ParamDynamic & param) {
    UInt32 *M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
    int s[] = { 7, 12, 17, 22 };
    for (int i = 0; i < 16; ++i) {
        UInt32 ti = k_ti_num_integer * abs(sin(i + 1));
        if (i % 4 == 0) {
            FF(param.ua_, param.ub_, param.uc_, param.ud_, M[i], s[i % 4], ti);
        }
        else if (i % 4 == 1) {
            FF(param.ud_, param.ua_, param.ub_, param.uc_, M[i], s[i % 4], ti);
        }
        else if (i % 4 == 2) {
            FF(param.uc_, param.ud_, param.ua_, param.ub_, M[i], s[i % 4], ti);
        }
        else if (i % 4 == 3) {
            FF(param.ub_, param.uc_, param.ud_, param.ua_, M[i], s[i % 4], ti);
        }
    }
}
void Md5Encode::RoundG(char *data_BIT_OF_GROUP_ptr, ParamDynamic & param) {
    UInt32 *M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
    int s[] = { 5, 9, 14, 20 };
    for (int i = 0; i < 16; ++i) {
        UInt32 ti = k_ti_num_integer * abs(sin(i + 1 + 16));
        int index = (i * 5 + 1) % 16;
        if (i % 4 == 0) {
            GG(param.ua_, param.ub_, param.uc_, param.ud_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 1) {
            GG(param.ud_, param.ua_, param.ub_, param.uc_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 2) {
            GG(param.uc_, param.ud_, param.ua_, param.ub_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 3) {
            GG(param.ub_, param.uc_, param.ud_, param.ua_, M[index], s[i % 4], ti);
        }
    }
}
void Md5Encode::RoundH(char *data_BIT_OF_GROUP_ptr, ParamDynamic & param) {
    UInt32 *M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
    int s[] = { 4, 11, 16, 23 };
    for (int i = 0; i < 16; ++i) {
        UInt32 ti = k_ti_num_integer * abs(sin(i + 1 + 32));
        int index = (i * 3 + 5) % 16;
        if (i % 4 == 0) {
            HH(param.ua_, param.ub_, param.uc_, param.ud_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 1) {
            HH(param.ud_, param.ua_, param.ub_, param.uc_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 2) {
            HH(param.uc_, param.ud_, param.ua_, param.ub_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 3) {
            HH(param.ub_, param.uc_, param.ud_, param.ua_, M[index], s[i % 4], ti);
        }
    }
}
void Md5Encode::RoundI(char *data_BIT_OF_GROUP_ptr, ParamDynamic & param) {
    UInt32 *M = reinterpret_cast<UInt32*>(data_BIT_OF_GROUP_ptr);
    int s[] = { 6, 10, 15, 21 };
    for (int i = 0; i < 16; ++i) {
        UInt32 ti = k_ti_num_integer * abs(sin(i + 1 + 48));
        int index = (i * 7 + 0) % 16;
        if (i % 4 == 0) {
            II(param.ua_, param.ub_, param.uc_, param.ud_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 1) {
            II(param.ud_, param.ua_, param.ub_, param.uc_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 2) {
            II(param.uc_, param.ud_, param.ua_, param.ub_, M[index], s[i % 4], ti);
        }
        else if (i % 4 == 3) {
            II(param.ub_, param.uc_, param.ud_, param.ua_, M[index], s[i % 4], ti);
        }
    }
}
void Md5Encode::RotationCalculate(char *data_512_ptr, ParamDynamic & param) {
    if (NULL == data_512_ptr) {
        return;
    }
    RoundF(data_512_ptr, param);
    RoundG(data_512_ptr, param);
    RoundH(data_512_ptr, param);
    RoundI(data_512_ptr, param);
    param.ua_ = param.va_last_ + param.ua_;
    param.ub_ = param.vb_last_ + param.ub_;
    param.uc_ = param.vc_last_ + param.uc_;
    param.ud_ = param.vd_last_ + param.ud_;

    param.va_last_ = param.ua_;
    param.vb_last_ = param.ub_;
    param.vc_last_ = param.uc_;
    param.vd_last_ = param.ud_;
}
// 转换成十六进制字符串输出
std::string Md5Encode::GetHexStr(unsigned int num_str) {
    std::string hexstr = "";
    char szch[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    unsigned char *tmptr = (unsigned char *)&num_str;
    int len = sizeof(num_str);
    // 小端字节序,逆序打印
    for (int i = 0; i < len; i++){
        unsigned char ch = tmptr[i] & 0xF0;
        ch = ch >> 4;
        hexstr.append(1, szch[ch]);
        ch = tmptr[i] & 0x0F;
        hexstr.append(1, szch[ch]);
    }
    return hexstr;
}
// function: Encode
// @param src_info:要加密的信息
// return :加密后的MD5值
std::string Md5Encode::Encode(std::string src_info) {
    ParamDynamic param;
    param.ua_ = kA;
    param.ub_ = kB;
    param.uc_ = kC;
    param.ud_ = kD;
    param.va_last_ = kA;
    param.vb_last_ = kB;
    param.vc_last_ = kC;
    param.vd_last_ = kD;
    std::string result;
    const char *src_data = src_info.c_str();
    char *out_data_ptr = NULL;
    int total_byte = FillData(src_data, strlen(src_data), &out_data_ptr);
    //char * data_BIT_OF_GROUP = out_data_ptr;
    for (int i = 0; i < total_byte / (BIT_OF_GROUP / BIT_OF_BYTE); ++i) {
        char * data_BIT_OF_GROUP = out_data_ptr;
        data_BIT_OF_GROUP += i*(BIT_OF_GROUP / BIT_OF_BYTE);
        RotationCalculate(data_BIT_OF_GROUP, param);
    }
    if (NULL != out_data_ptr) {
        delete[] out_data_ptr, out_data_ptr = NULL;
    }
    result.append(GetHexStr(param.ua_));
    result.append(GetHexStr(param.ub_));
    result.append(GetHexStr(param.uc_));
    result.append(GetHexStr(param.ud_));
    return result;
}

测试:

#include <iostream>
#include <cmath>
#include "md5_encode.h"

int main(int argc, char* argv[]) {
    std::string src = "fasdfasdfasdfnmmw,enrsudfnsmndfejkjhuasdmnf";
    Md5Encode encode_obj;
    std::string ret = encode_obj.Encode(src);
    std::cout << "info: " << src.c_str() << std::endl;
    std::cout << "md5: " << ret.c_str() << std::endl;
    return 0;
}

结果:

info: fasdfasdfasdfnmmw,enrsudfnsmndfejkjhuasdmnf
md5: 01109ec97162a71ca5e67b5f059c3cac

到此这篇关于c++实现md5加密的文章就介绍到这了,更多相关c++ md5加密内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java C++实现相同MD5加密算法的方式

    目录 Java与C++实现相同的MD5加密算法 1.Java版 2.C++代码 3.运行效果 Java与C++实现相同的MD5加密算法 1.Java版 package com.lyz.utils.common; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * MD5加密 * @a

  • Java与C++实现相同的MD5加密算法简单实例

    1.Java版 package com.lyz.utils.common; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /** * MD5加密 * @author liuyazhuang */ public class MD5Hash { public static String md5

  • .NET MD5加密解密代码解析

    MD5简介: 是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数).不管是MD2.MD4还是MD5,它们都需要获得一个随机长度的信息并产生一个128位的信息摘要.虽然这些算法的结构或多或少有些相似,但MD2的设计与MD4和MD5完全不同,那是因为MD2是为8位机器做过设计优化的,而MD4和MD5却是面向32位的电脑.这三个算法的描述和C语言源代码在Internet RFCs 1321中有详细的描述,这是一份最权威的文档

  • java MD5加密实现代码

    先从下面这张图对MD5加密实现进行了解,具体如下 package com.pb; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Scanner; /* * 验证MD5 * 1.初始化MessageDigest信息摘要对象 * 2.传入需要计算的字符串更新摘

  • Java生成MD5加密字符串代码实例

    (1)一般使用的数据库中都会保存用户名和密码,其中密码不使用明码保存.     有时候用MD5密码,很多语言都提供了将字符串生成为MD5密码的方法或函数.MD5的加密算法是公开的.     有时候也可以用自己的字符串加密算法,这种加密算法是只有自己知道的. (2)破解MD5的过程就是先算好大量或者所有可能的字符串的MD5数值,之后进行查询就可以破解.虽然有些网站规定了密码的位数在6~20位之间,但是要事先计算这么多是字符串并有效的组织存储.查询还是相当麻烦,相当慢的. 因为MD5的位数是固定的,

  • c++实现md5加密的代码

    最近发现md5加密算法挺有趣,特点是单向加密不可逆,加密后的字符串长度相等,于是就用C++尝试实现了一下 头文件定义 /* ******************************************************* * brief: md5 encryption * author: Monkey.Knight ******************************************************* */ #ifndef __MD5_ENCODE_H__

  • jQuery MD5加密实现代码

    $(md("你想要加密的字符串")); md5插件下载地址:http://xiazai.jb51.net/201003/yuanma/jquery_md5.rar 下面是我的简单例子 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"

  • VB实现的16位和32位md5加密代码分享

    在各种登陆系统中,用户密码的md5加密是不可少的. 这么说吧,即使你通过各种手段看到了用户的登陆密码,但那一串古古怪怪的东西你也不可能知道它是什么,这就是保护. md5加密运算是不可逆的,就是说你不能通过那一串古古怪怪的东西算出它原始的样子. 下面是完整的md5代码,不要去理解算法了,用到时拿去直接调用. Private Const BITS_TO_A_BYTE = 8 Private Const BYTES_TO_A_WORD = 4 Private Const BITS_TO_A_WORD

  • Java实现MD5加密及解密的代码实例分享

    基础:MessageDigest类的使用 其实要在Java中完成MD5加密,MessageDigest类大部分都帮你实现好了,几行代码足矣: /** * 对字符串md5加密 * * @param str * @return */ import java.security.MessageDigest; public static String getMD5(String str) { try { // 生成一个MD5加密计算摘要 MessageDigest md = MessageDigest.g

  • 详解C#实现MD5加密的示例代码

    C#实现MD5加密,具体如下: 方法一 首先,先简单介绍一下MD5 MD5的全称是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest开发出来, 经md2.md3和md4发展而来. MD5具有很好的安全性(因为它具有不可逆的特征,加过密的密文经过解密后和加密前的东东相同的可能性极小) 引用 using System.S

  • android md5加密与rsa加解密实现代码

    复制代码 代码如下: import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5 { /* * MD5加密 */ public static String getDigest(String str) { MessageDigest messageDigest = nul

  • 微信小程序 MD5加密登录密码详解及实例代码

    微信小程序 MD5加密 在小程序中,页面的脚本逻辑是在JsCore中运行,JsCore是一个没有窗口对象的环境,所以不能在脚本中使用window,也无法在脚本中操作组件.zepto/jquery 也无法使用,因为zepto/jquery 会使用到window对象和document对象.所以在微信小程序中不能使用jquery.md5.js对密码进行加密.下面我提供一种MD5.js加密实例,本实例先静态演示,后面再到小程序中演示. md5.js程序如下: /* * A JavaScript impl

随机推荐