📄 md5_b.cpp
字号:
/* MD5 message-digest algorithm */
typedef unsigned char * POINTER; //无符号字符指针
typedef unsigned short int UINT2; //双字节无符号整数
typedef unsigned long int UINT4; //4字节无符号整数
/* MD5 context */
typedef struct {
UINT4 state[4]; // state(ABCD)
UINT4 count[2]; // number of bits,modulo 2^64(lsb first)
unsigned char buffer[64]; // 16字输入缓冲
} MD5_CTX;
void MD5Init(MD5_CTX *); //MD5初始化:A,B,C,D置初值
void MD6Update(MD5_CTX *,unsigned char *,unsigned int);
void MD5Final(unsigned char [16],MD5_CTX *);
static void MD5Transform(UINT4 [4],unsigned char [64]);
static void Encode(unsigned char *,UINT4 *,unsigned int);
static void Decode(UINT4 *,unsigned char *,unsigned int);//每4个字节转换为1个无符号Long
static void MD5_memcpy(POINTER,POINTER,unsigned int);
static void MD5_memset(POINTER,int,unsigned int);
static unsigned char PADDING[64] = {0x80,0};
UINT4 t[64] = { //T[i]=2^32×|sin(i)|, i=1,2,…,64
0xd76aa478L,0xe8c7b756L,0x242070dbL,0xc1bdceeeL,
0xf57c0fafL,0x4787c62aL,0xa8304613L,0xfd469501L,
0x698098d8L,0x8b44f7afL,0xffff5bb1L,0x895cd7beL,
0x6b901122L,0xfd987193L,0xa679438eL,0x49b40821L,
0xf61e2562L,0xc040b340L,0x265e5a51L,0xe9b6c7aaL,
0xd62f105dL,0x02441453L,0xd8a1e681L,0xe7d3fbc8L,
0x21e1cde6L,0xc33707d6L,0xf4d50d87L,0x455a14edL,
0xa9e3e905L,0xfcefa3f8L,0x676f02d9L,0x8d2a4c8aL,
0xfffa3942L,0x8771f681L,0x6d9d6122L,0xfde5380cL,
0xa4beea44L,0x4bdecfa9L,0xf6bb4b60L,0xbebfbc70L,
0x289b7ec6L,0xeaa127faL,0xd4ef3085L,0x04881d05L,
0xd9d4d039L,0xe6db99e5L,0x1fa27cf8L,0xc4ac5665L,
0xf4292244L,0x432aff97L,0xab9423a7L,0xfc93a039L,
0x655b59c3L,0x8f0ccc92L,0xffeff47dL,0x85845dd1L,
0x6fa87e4fL,0xfe2ce6e0L,0xa3014314L,0x4e0811a1L,
0xf7537e82L,0xbd3af235L,0x2ad7d2bbL,0xeb86d391L };
int S1[] = {7,12,17,22},S2[] = {5,9,14,20}; //第1、2轮的s值
int S3[] = {4,11,16,23},S4[] = {6,10,15,21}; //第3、4轮的s值
int ng[16] = {1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12};//第2轮的k值
int nh[16] = {5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2};//第3轮的k值
int ni[16] = {0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9};//第4轮的k值
/* F,G,H and I are basic MD5 functions. */
UINT4 F(UINT4 x,UINT4 y,UINT4 z) //辅助函数F
{
return ((x & y)|(~x & z));
}
UINT4 G(UINT4 x,UINT4 y,UINT4 z) //辅助函数G
{
return ((x & z)|(y & (~z)));
}
UINT4 H(UINT4 x,UINT4 y,UINT4 z) //辅助函数H
{
return (x ^ y ^ z);
}
UINT4 I(UINT4 x,UINT4 y,UINT4 z) //辅助函数H
{
return (y ^ (x | (~z)));
}
/* FGHI transformations for rounds 1,2,3 and 4.
* Rotation is separate from addition to prevent recomputation.
*/
void FGHI(UINT4 *a,UINT4 b,UINT4 c,UINT4 d,UINT4 x,int s,UINT4 ac,UINT4 (*f)(UINT4,UINT4,UINT4))
{
*a += (*f)(b,c,d) + x + ac;
*a = (*a << s)|(*a >> (32-s)); //循环左移s位
*a += b; //结果由*a返回
}
/* MD5 initialization.
Begins an MD5 operation,working a new context.
*/
void MD5Init(MD5_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants */
context->state[0] = 0x67452301; //A的初始值
context->state[1] = 0xefcdab89; //B的初始值
context->state[2] = 0x98badcfe; //C的初始值
context->state[3] = 0x10325476; //D的初始值
}
/* MD5 block update operation.Continues an MD5 message-digest operation,
processing another message block,and update the context.
*/
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputLen)
{ //input:输入块;inputLen:输入块长度(字节数)
unsigned int i,index,partLen;
// Compute number of bytes mod 64
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
// Update number of bits
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
partLen = 64 - index;
// Transform an many times as possible.
if (inputLen >= partLen) {
MD5_memcpy(&context->buffer[index],input,partLen);
MD5Transform(context->state,context->buffer);
for (i=partLen; i+63<inputLen;i+=64)
MD5Transform(context->state,&input[i]);
index = 0;
}
else i = 0;
/* Buffer remaining input */
MD5_memcpy(&context->buffer[index],&input[i],inputLen-i);
}
/* MD5 finalization.Ends an MD5 message-digest operation,
writing the message-digest and zeroizing the context.
*/
void MD5Final(unsigned char digest[16],MD5_CTX * context)
{
unsigned char bits[8];
unsigned int index,padLen;
/* Save number of bits */
Encode(bits,context->count,8);
/* Pad out to 56 mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56)? (56-index):(120-index);
MD5Update(context,PADDING,padLen);
/* Append length (before padding) */
MD5Update(context,bits,8);
/* Store state in digest */
Encode(digest,context->state,16);
/* Zeroize sensitive information. */
MD5_memset((POINTER)context,0,sizeof(*context));
}
/* MD5 basic transformation.Transforms state based on block. */
static void MD5Transform(UINT4 state[4],unsigned char block[64])
{
UINT4 a=state[0],b=state[1],c=state[2],d=state[3],x[16];
int i,j;
Decode(x,block,64);
/* round 1 */
for (i=j=0; i<4; i++,j+=4) {
FGHI(&a,b,c,d,x[j],S1[0],t[j],F);
FGHI(&d,a,b,c,x[j+1],S1[1],t[j+1],F);
FGHI(&c,d,a,b,x[j+2],S1[2],t[j+2],F);
FGHI(&b,c,d,a,x[j+3],S1[3],t[j+3],F);
}
/* round 2 */
for (i=j=0; i<4; i++,j+=4) {
FGHI(&a,b,c,d,x[ng[j]],S2[0],t[16+j],G);
FGHI(&d,a,b,c,x[ng[j+1]],S2[1],t[17+j],G);
FGHI(&c,d,a,b,x[ng[j+2]],S2[2],t[18+j],G);
FGHI(&b,c,d,a,x[ng[j+3]],S2[3],t[19+j],G);
}
/* round 3 */
for (i=j=0; i<4; i++,j+=4) {
FGHI(&a,b,c,d,x[nh[j]],S3[0],t[32+j],H);
FGHI(&d,a,b,c,x[nh[j+1]],S3[1],t[33+j],H);
FGHI(&c,d,a,b,x[nh[j+2]],S3[2],t[34+j],H);
FGHI(&b,c,d,a,x[nh[j+3]],S3[3],t[35+j],H);
}
/* round 4 */
for (i=j=0; i<4; i++,j+=4) {
FGHI(&a,b,c,d,x[ni[j]],S4[0],t[48+j],I);
FGHI(&d,a,b,c,x[ni[j+1]],S4[1],t[49+j],I);
FGHI(&c,d,a,b,x[ni[j+2]],S4[2],t[50+j],I);
FGHI(&b,c,d,a,x[ni[j+3]],S4[3],t[51+j],I);
}
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
MD5_memset((POINTER)x,0,sizeof(x));
}
/* Encode input (UNT4) into output (unsigned char).
Assumes len is a multiple of 4.
*/
static void Encode(unsigned char *output,UINT4 * input,unsigned int len)
{ //每1个unsigned long转换成4个unsigned char
unsigned int i,j;
for (i=j=0; j<len; i++,j+=4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >>16) & 0xff);
output[j+3] = (unsigned char)((input[i] >>24) & 0xff);
}
}
/* Decode input (unsigned char)into output (UINT4).
Assumes len is a multiple of 4.
*/
static void Decode(UINT4 *output,unsigned char *input,unsigned int len)
{
unsigned int i,j;
for (i=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);
}
/* Note:Replace "for loop" with standard memcpy if possible. */
static void MD5_memcpy(POINTER output,POINTER input,unsigned int len)
{
unsigned int i;
for (i=0;i<len;i++) output[i] = input[i];
}
/* Note:Replace "for loop" with standard memcpy if possible. */
static void MD5_memset(POINTER output,int value,unsigned int len)
{
unsigned int i;
for (i=0;i<len;i++) ((char *)output)[i] = (char)value;
}
/* Test MD5.C */
#include <stdio.h>
#include <iostream.h>
#include <iomanip.h> //setfill()
#include <process.h> //exit()
#define LEN 2048
void main()
{
FILE *fp;
unsigned char text[LEN],FName[100],digest[16];
const char *FN=(const char *)FName;
int i;
MD5_CTX *context,block;
cout<<"Enter the file name : ";
cin>>FName;
if (!(fp = fopen(FN,"rb")))
{ cout<<"Cannot open file "<<FName<<endl;
exit(0);
}
context = █
MD5Init(context);
while (!feof(fp))
{
for (i=0;!feof(fp) && i<LEN; i++) text[i] = getc(fp);
if (feof(fp)) i--;
MD5Update(context,text,i);
}
fclose(fp);
MD5Final(digest,context);
cout<<"\nThe data file name : "<<FName;
cout<<"\nThe message-digest : ";
for (i=0; i<16; i++)
cout<<setfill('0')<<hex<<(int)digest[i]<<" ";
cout<<"\n\n";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -