⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md5_b.cpp

📁 计算机网络安全中的DES加密解密算法
💻 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 = &block;
  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 + -