md5C++加密

原创 2016年06月02日 12:46:09

我们的课程设计MD5生成散列值,从百度上找的程序,自己加了一些注释,有的地方还是不是很理解。具体如下:

源代码链接:http://baike.baidu.com/link?url=_gK4qMl2mkKuSK6AFAKsV5ksbyAuP9J6Aij-kAU8h9jB8CBVUEvq93EoF4eWCzd949KkUDK8xoXgdp_eEtrm5q

我的注释如下:

希望可以给你们一点帮助

#include<iostream>
#include<string>
using namespace std;
#define shift(x, n) (((x) << (n)) | ((x) >> (32-(n))))//右移的时候,高位一定要补零,而不是补充符号位
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476
//strBaye的长度
unsigned int strlength;
//A,B,C,D的临时变量
unsigned int atemp;
unsigned int btemp;
unsigned int ctemp;
unsigned int dtemp;
//常量ti unsigned int(abs(sin(i+1))*(2pow32))
const unsigned int k[]={
        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};
//向左位移数
const unsigned int s[]={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};
const char str16[]="0123456789abcdef";
void mainLoop(unsigned int M[])
{
    unsigned int f,g;
    unsigned int a=atemp;
    unsigned int b=btemp;
    unsigned int c=ctemp;
    unsigned int d=dtemp;
    for (unsigned int i = 0; i < 64; i++)
    {
        //16轮,每一轮以不同的次序使用16个字,其中在第一轮以字的初始次序使用
        //第2轮到第四轮,分别对字的次序做置换得到一个新的次序,然后使用新次序使用16个字

        if(i<16){
            f=F(b,c,d);
            g=i;
        }else if (i<32)
        {
            f=G(b,c,d);
            g=(5*i+1)%16;  //p2(i)=(1+5i)mod16
        }else if(i<48){
            f=H(b,c,d);
            g=(3*i+5)%16;  //p3(i)=(5+3i)mod16
        }else{
            f=I(b,c,d);
            g=(7*i)%16;     //p4(i)=7*i mod 16
        }
        unsigned int tmp=d;
        d=c;    //d=c
        c=b;   //c=b
        b=b+shift((a+f+k[i]+M[g]),s[i]); //b=b运算后的结果
        a=tmp; //a=d
    }
    atemp=a+atemp;
    btemp=b+btemp;
    ctemp=c+ctemp;
    dtemp=d+dtemp;
}
/*
*填充函数
*处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
*填充方式为先加一个1,其它位补零
*最后加上64位的原来长度
*/
unsigned int* add(string str)
{

    //cout<<str.length()<<endl; //6

    //进行分组,以512位进行分组,
    //str.length()+8 是因为对消息进行填充,然后比特长为模512下为448,
    //然后需要留出64位,1个字节8个位,所以+8
    unsigned int num=((str.length()+8)/64)+1;//以512位,64个字节为一组

    //每一个分组都可以表示为16个32比特长的字,(32/8=4字节),32*16=512
    unsigned int *strByte=new unsigned int[num*16];    //64/4=16,所以有16个整数

    strlength=num*16;  //因为只有1个分组,所以strlength为16


    //进行初始化,使数组里面的值初始化为0
    for (unsigned int i = 0; i < num*16; i++)
        strByte[i]=0;


    for (unsigned int i=0; i <str.length(); i++)
    {
        //i>>2 ==i/4
        strByte[i/4]|= (str[i])<<((i%4)*8);//一个整数存储四个字节,i>>2表示i/4 一个unsigned int对应4个字节,保存4个字符信息
        //小端排序  一个整形的int存放了4个char字串[6][5][4][3][2][1]
    }
    //0x80 ===128==10000000   128<<16
    strByte[str.length()/4]|=128<<(((str.length()%4))*8);//尾部添加1 一个unsigned int保存4个字符信息,所以用128左移
    /*
    *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
    */


    strByte[num*16-2]=str.length()*8;

    return strByte;
}

/*

*/
string changeHex(int a)
{

    int b;
    string str1;
    string str="";  //定义的char类型,然后每一个字符占一个位,8个字节
    for(int i=0;i<4;i++)
    {
        str1="";
        b=((a>>i*8)%(1<<8))&255;  //&0xff=255 1111111
          //逆序处理每个字节  字节  1个字节8个为 int 类型 4个位32个字节 256 16^2   123456   char 类型,然而一个int存放4个char
        //一个16进制的数等于4位二进制的数,一个字节等于8位二进制的数

        for (int j = 0; j < 2; j++)
        {
            //1个字节8个位1个整型是4个字节,一个char是1个字节
            str1.insert(0,1,str16[b%16]); //const char str16[]="0123456789abcdef";

            //转换为16进制存起来,然而str1是多少进制的啊?
            /*
                  c.insert(pos,elem)
                  c.insert(pos,n,elem)
                  c.insert(pos,beg,end)
  在pos位置插入一个elem拷贝,传回新数据位置。
  在pos位置插入n个elem数据。无返回值。
  在pos位置插入在[beg,end)区间的数据。无返回值。
            */
            b=b/16;
        }
        str+=str1;

    }

    return str;
}
string getMD5(string source)
{
    atemp=A;    //初始化
    btemp=B;
    ctemp=C;
    dtemp=D;
    unsigned int *strByte=add(source);  //扩展函数
    //cout<<strlength<<endl;
    for(unsigned int i=0;i<strlength/16;i++)
    {
        unsigned int num[16];
        for(unsigned int j=0;j<16;j++)
        {
            num[j]=strByte[i*16+j];

        }

        mainLoop(num);
    }

    return changeHex(atemp).append(changeHex(btemp)).append(changeHex(ctemp)).append(changeHex(dtemp));
}
 int main()
{
    int n;
    string ss;
    cout<<"请输入您要生成消息摘要的字符串的组数"<<endl;
    cin>>n;

    while(n--){
    cout<<"请输入您要生成消息摘要的字符串:"<<endl;
    cin>>ss;
    string s=getMD5(ss);
    cout<<"您生成的消息摘要是"<<endl;
    cout<<s<<endl;

    }



    return 0;
}
做完以后,最后答辩的时候,老师看的是我用PHP写的那个注册和登陆的模块,并没有问我这个找的代码,最后还是生成了MD5散列值!总结:自己的编码能力还是太差劲,多多了解算法,多做一些acm的题!加油!向哪些大神看齐!


版权声明:本文为博主原创文章,未经博主允许不得转载。

Java与C++实现相同的MD5加密算法

原文转自:http://blog.csdn.net/l1028386804/article/details/47025267 1、Java版 [java] ...

C++实现md5加密或计算文件的唯一性识别

由于网络上传了很多关于C++实现md5加密的类,至于那个是原创,我不敢妄加猜测,只是这里我声明我是转载的,并支持原创。 对于md5加密算法,我提供两文件: [cpp] vi...

C++ 之 md5加密解密 实现类

1. IntroductionMD5算法是一种消息摘要算法(Message Digest Algorithm),此算法以任意长度的信息(message)作为输入进行计算,产生一个128-bit(16-...
  • asb2010
  • asb2010
  • 2015年01月23日 14:12
  • 1969

C/C++使用openssl进行摘要和加密解密(md5, sha256, des, rsa)

penssl里面有很多用于摘要哈希、加密解密的算法,方便集成于工程项目,被广泛应用于网络报文中的安全传输和认证。下面以md5,sha256,des,rsa几个典型的api简单使用作为例子。   ...

C++ MD5字符串加密

获取字符串的32位md5码.仅能在vc编译器下,计算结果正确。

C++ VC MD5加密(信息摘要算法)示例

md5c.c md5.h 上面两个文件,是网上开源的两个文件,应用最多的。
  • jsjrj01
  • jsjrj01
  • 2014年05月09日 20:14
  • 1187

C++ MD5加密实现

转自:http://blog.csdn.net/gf771115/article/details/24584199#pragma once #ifndef BZF_MD5_H #define BZ...

c++ 加密MD5/SHA1/BASE64

一、常用加密情况有三种 : 1. 资源加密,如图片,音乐(防盗版) 2. 网络传输过程中的加密,避免被人拦截并修改数据(防作弊) 3. 游戏数据加密(防作弊) 二、...

主要是C++版本的MD5加密代码

  • 2017年11月24日 11:39
  • 10KB
  • 下载

MD5加密算法C++实现

  • 2014年05月27日 18:29
  • 5MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:md5C++加密
举报原因:
原因补充:

(最多只允许输入30个字)