【C】C语言实现MD5算法
现在MD5已被证实其并不安全了!不过它也还是有些作用的。//=============================================================================//作者:0xAA55
//网站:http://www.0xaa55.com
//版权所有(C)技术宅的结界 2013-2015
//请保留原作者信息,否则视为侵权
//-----------------------------------------------------------------------------
//rfc1321
#include"md5.h"
#include<memory.h>
//MD5寄存器
typedef struct
{
uint32_t A;
uint32_t B;
uint32_t C;
uint32_t D;
uint32_t AA;
uint32_t BB;
uint32_t CC;
uint32_t DD;
}MD5Registers,*MD5RegistersP;
static uint32_t F(uint32_t x,uint32_t y,uint32_t z){return (x&y)|(~x&z);}
static uint32_t G(uint32_t x,uint32_t y,uint32_t z){return (x&z)|(y&~z);}
static uint32_t H(uint32_t x,uint32_t y,uint32_t z){return x^y^z;}
static uint32_t I(uint32_t x,uint32_t y,uint32_t z){return y^(x|~z);}
static uint32_t Rol(uint32_t v,uint8_t Count){return (v<<Count)|(v>>(32-Count));}
static uint32_t FF(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
uint32_t X,uint32_t s,uint32_t T)
{return b+Rol((a+F(b,c,d)+X+T),s);}
static uint32_t GG(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
uint32_t X,uint32_t s,uint32_t T)
{return b+Rol((a+G(b,c,d)+X+T),s);}
static uint32_t HH(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
uint32_t X,uint32_t s,uint32_t T)
{return b+Rol((a+H(b,c,d)+X+T),s);}
static uint32_t II(uint32_t a,uint32_t b,uint32_t c,uint32_t d,
uint32_t X,uint32_t s,uint32_t T)
{return b+Rol((a+I(b,c,d)+X+T),s);}
//=============================================================================
//函数:InitRegs
//描述:初始化MD5寄存器
//-----------------------------------------------------------------------------
static void InitRegs(MD5RegistersP pReg)
{
//初始4个32位寄存器
pReg->A=0x67452301;
pReg->B=0xEFCDAB89;
pReg->C=0x98BADCFE;
pReg->D=0x10325476;
}
//=============================================================================
//函数:DigestChunk
//描述:将一个64字节的“块”作为数据压入计算
//-----------------------------------------------------------------------------
static void DigestChunk(MD5RegistersP pReg,void*pData)
{
# define p ((uint32_t*)pData)
pReg->AA=pReg->A;
pReg->BB=pReg->B;
pReg->CC=pReg->C;
pReg->DD=pReg->D;
pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p,0x07,0xD76AA478);
pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0C,0xE8C7B756);
pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p,0x11,0x242070DB);
pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p,0x16,0xC1BDCEEE);
pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p,0x07,0xF57C0FAF);
pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0C,0x4787C62A);
pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p,0x11,0xA8304613);
pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p,0x16,0xFD469501);
pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p,0x07,0x698098D8);
pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0C,0x8B44F7AF);
pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p,0x11,0xFFFF5BB1);
pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p,0x16,0x895CD7BE);
pReg->A=FF(pReg->A,pReg->B,pReg->C,pReg->D,p,0x07,0x6B901122);
pReg->D=FF(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0C,0xFD987193);
pReg->C=FF(pReg->C,pReg->D,pReg->A,pReg->B,p,0x11,0xA679438E);
pReg->B=FF(pReg->B,pReg->C,pReg->D,pReg->A,p,0x16,0x49B40821);
pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p,0x05,0xF61E2562);
pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p,0x09,0xC040B340);
pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0E,0x265E5A51);
pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p,0x14,0xE9B6C7AA);
pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p,0x05,0xD62F105D);
pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p,0x09,0x02441453);
pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0E,0xD8A1E681);
pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p,0x14,0xE7D3FBC8);
pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p,0x05,0x21E1CDE6);
pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p,0x09,0xC33707D6);
pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0E,0xF4D50D87);
pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p,0x14,0x455A14ED);
pReg->A=GG(pReg->A,pReg->B,pReg->C,pReg->D,p,0x05,0xA9E3E905);
pReg->D=GG(pReg->D,pReg->A,pReg->B,pReg->C,p,0x09,0xFCEFA3F8);
pReg->C=GG(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0E,0x676F02D9);
pReg->B=GG(pReg->B,pReg->C,pReg->D,pReg->A,p,0x14,0x8D2A4C8A);
pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p,0x04,0xFFFA3942);
pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0B,0x8771F681);
pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p,0x10,0x6D9D6122);
pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p,0x17,0xFDE5380C);
pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p,0x04,0xA4BEEA44);
pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0B,0x4BDECFA9);
pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p,0x10,0xF6BB4B60);
pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p,0x17,0xBEBFBC70);
pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p,0x04,0x289B7EC6);
pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0B,0xEAA127FA);
pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p,0x10,0xD4EF3085);
pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p,0x17,0x04881D05);
pReg->A=HH(pReg->A,pReg->B,pReg->C,pReg->D,p,0x04,0xD9D4D039);
pReg->D=HH(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0B,0xE6DB99E5);
pReg->C=HH(pReg->C,pReg->D,pReg->A,pReg->B,p,0x10,0x1FA27CF8);
pReg->B=HH(pReg->B,pReg->C,pReg->D,pReg->A,p,0x17,0xC4AC5665);
pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p,0x06,0xF4292244);
pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0A,0x432AFF97);
pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0F,0xAB9423A7);
pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p,0x15,0xFC93A039);
pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p,0x06,0x655B59C3);
pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0A,0x8F0CCC92);
pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0F,0xFFEFF47D);
pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p,0x15,0x85845DD1);
pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p,0x06,0x6FA87E4F);
pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0A,0xFE2CE6E0);
pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0F,0xA3014314);
pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p,0x15,0x4E0811A1);
pReg->A=II(pReg->A,pReg->B,pReg->C,pReg->D,p,0x06,0xF7537E82);
pReg->D=II(pReg->D,pReg->A,pReg->B,pReg->C,p,0x0A,0xBD3AF235);
pReg->C=II(pReg->C,pReg->D,pReg->A,pReg->B,p,0x0F,0x2AD7D2BB);
pReg->B=II(pReg->B,pReg->C,pReg->D,pReg->A,p,0x15,0xEB86D391);
pReg->A+=pReg->AA;
pReg->B+=pReg->BB;
pReg->C+=pReg->CC;
pReg->D+=pReg->DD;
}
//=============================================================================
//函数:MD5Sum
//描述:计算MD5校验和,其中pMD5Out接收结果(函数将写入16个字节到pMD5Out)
//-----------------------------------------------------------------------------
void MD5Sum
(
void *pData, //数据指针
size_t cbData, //数据大小(Bytes)
uint32_t *pMD5Out//输出MD5
)
{
MD5Registers Regs={0};
uint8_t PadBuf={0};//用于计算最后的填充内容的缓冲区
size_t i;
size_t cbLast=cbData;
//=========================================================================
//MD5算法:
//第一:数据补充
//1、将数据看成是bit流,在最后一个bit的后面添加一个1。
//2、再在数据的后面不断补充0,直到数据的总位数与512求余==448
//3、将数据的总位数以uint64_t格式补充到最后
//第二:运算
//1、初始化MD5寄存器
//2、将数据划分为n个512 bit的块,对每个块进行DigestChunk运算
//3、最后将MD5寄存器的值返回
//初始化MD5寄存器
InitRegs(&Regs);
//将数据拆成64字节一个块,先分析逐个块,直到最后一个块(然后再来处理“补齐”)
for(i=0;i+64<=cbData;i+=64)
{
DigestChunk(&Regs,pData);
(uint8_t*)pData+=64;
cbLast-=64;
}
//如果最后一个块有内容则复制到最后的填充内容的缓冲区
if(cbData)
memcpy(PadBuf,pData,cbLast);
//补充1
PadBuf=0x80;
//然后在这个填充数据块的结尾补充[数据的总位数]。
//如果有空余的空间可用于补充,则补充
if(cbLast<56)
{
*(uint64_t*)&(PadBuf)=(uint64_t)cbData*8;
DigestChunk(&Regs,PadBuf);
}
else//否则再补充56个,然后再补充
{
DigestChunk(&Regs,PadBuf);
memset(PadBuf,0,sizeof(PadBuf));
*(uint64_t*)&(PadBuf)=(uint64_t)cbData*8;
DigestChunk(&Regs,PadBuf);
}
//最后返回MD5寄存器的值
pMD5Out=Regs.A;
pMD5Out=Regs.B;
pMD5Out=Regs.C;
pMD5Out=Regs.D;
}以下程序用于计算一个字符串的MD5值。
命令:md5 <string>
BIN:
SRC:
页:
[1]