md5 算法的c语言实现及应用
2013年10月24日
⁄ 综合
⁄ 共 13905字 ⁄ 字号
小 中 大
- #由于工作需要,稍微学了学md5方面的知识,现分享给大家,不耻聆听指教。
- #运行环境linux2.4以上。
- ##########
- # md5.h #
- ##########
- #ifndef MD5_H
- #define MD5_H
- #define md5byte unsigned char
- #define SIZEOF_UNSIGNED_LONG 4
- #if SIZEOF_UNSIGNED_LONG== 4
- # define UWORD32 unsigned long
- #elif SIZEOF_UNSIGNED_INT==4
- # define UWORD32 unsigned int
- #else
- # error I do not know what to use for a UWORD32.
- #endif
- typedef struct MD5Context
- {
- UWORD32 buf[4];
- UWORD32 bytes[2];
- UWORD32 in[16];
- } MD5_CTX;
- void MD5Init(struct MD5Context *context);
- void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
- void MD5Final(unsigned char digest[16], struct MD5Context *context);
- void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
- #define STACK_SIZE 512
- #define MD5SUMS "md5sums"
- typedef struct md5arc
- {
- char dirname[STACK_SIZE];
- char md5string[32];
- }md5_arc;
- typedef struct stack
- {
- char file_dir[STACK_SIZE];
- int top;
- }str_dir;
- static void MDString (char *string);
- void md5_to_string(unsigned char *unx,char *string);
- static void MDFile(const char *filename,char *store);
- #endif
- ############
- # md5.c #
- ############
- #include <string.h> /* for memcpy() */
- #include <sys/types.h> /* for stupid systems */
- #include <netinet/in.h> /* for ntohl() */
- #include "md5.h"
- #ifdef WORDS_BIGENDIAN
- void
- byteSwap(UWORD32 *buf, unsigned words)
- {
- md5byte *p = (md5byte *)buf;
- do {
- *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
- ((unsigned)p[1] << 8 | p[0]);
- p += 4;
- } while (--words);
- }
- #else
- #define byteSwap(buf,words)
- #endif
- void
- MD5Init(struct MD5Context *ctx)
- {
- ctx->buf[0] = 0x67452301;
- ctx->buf[1] = 0xefcdab89;
- ctx->buf[2] = 0x98badcfe;
- ctx->buf[3] = 0x10325476;
- ctx->bytes[0] = 0;
- ctx->bytes[1] = 0;
- }
- void
- MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
- {
- UWORD32 t;
-
-
-
- t = ctx->bytes[0];
- if ((ctx->bytes[0] = t + len) < t)
- ctx->bytes[1]++;
-
- t = 64 - (t & 0x3f);
- if (t > len) {
- memcpy((md5byte *)ctx->in + 64 - t, buf, len);
- return;
- }
-
- memcpy((md5byte *)ctx->in + 64 - t, buf, t);
- byteSwap(ctx->in, 16);
- MD5Transform(ctx->buf, ctx->in);
- buf += t;
- len -= t;
-
- while (len >= 64) {
- memcpy(ctx->in, buf, 64);
- byteSwap(ctx->in, 16);
- MD5Transform(ctx->buf, ctx->in);
- buf += 64;
- len -= 64;
- }
-
-
- memcpy(ctx->in, buf, len);
- }
- void
- MD5Final(md5byte digest[16], struct MD5Context *ctx)
- {
- int count = ctx->bytes[0] & 0x3f;
- md5byte *p = (md5byte *)ctx->in + count;
-
- *p++ = 0x80;
-
- count = 56 - 1 - count;
- if (count < 0) {
- memset(p, 0, count + 8);
- byteSwap(ctx->in, 16);
- MD5Transform(ctx->buf, ctx->in);
- p = (md5byte *)ctx->in;
- count = 56;
- }
- memset(p, 0, count);
- byteSwap(ctx->in, 14);
-
-
- ctx->in[14] = ctx->bytes[0] << 3;
- ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
- MD5Transform(ctx->buf, ctx->in);
-
- byteSwap(ctx->buf, 4);
- memcpy(digest, ctx->buf, 16);
- memset(ctx, 0, sizeof(ctx));
- }
- #ifndef ASM_MD5
- #define F1(x, y, z) (z ^ (x & (y ^ z)))
- #define F2(x, y, z) F1(z, x, y)
- #define F3(x, y, z) (x ^ y ^ z)
- #define F4(x, y, z) (y ^ (x | ~z))
- #define MD5STEP(f,w,x,y,z,in,s) /
- (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
- void
- MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
- {
- register UWORD32 a, b, c, d;
- a = buf[0];
- b = buf[1];
- c = buf[2];
- d = buf[3];
-
- MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
- MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
- MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
- MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
- MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
- MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
- MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
- MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
- MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
- MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
- MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
- MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
- MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
- MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
- MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
- MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
- MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
- MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
- MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
- MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
- MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
- MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
- MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
- MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
- MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
- MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
- MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
- MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
- MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
- MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
- MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
- MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
- MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
- MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
- MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
- MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
- MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
- MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
- MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
- MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
- MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
- MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
- MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
- MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
- MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
- MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
- MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
- MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
- MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
- MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
- MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
- MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
- MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
- MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
- MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
- MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
- MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
- MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
- MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
- MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
- MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
- MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
- MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
- MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
- buf[0] += a;
- buf[1] += b;
- buf[2] += c;
- buf[3] += d;
- }
- #endif
- ####################
- # md5sum.c #
- # md5的一些应用程序 #
- ####################
- #include <stdio.h>
- #include <fcntl.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <errno.h>
- #include "md5.h"
- static void MDPrint (unsigned char digest[1])
- {
- unsigned int i;
- printf("/n");
- for(i = 0; i < 16; i++)
- printf("%02x", digest[i]);
- }
- static void MDString (char *string)
- {
- MD5_CTX context;
- unsigned char digest[16];
- unsigned int len = strlen(string);
- MD5Init(&context);
- MD5Update(&context, string, len);
- MD5Final(digest, &context);
- printf("%s = ", string);
- MDPrint(digest);
- printf("/n");
- }
- void
- md5_to_string(unsigned char *unx,char *string)
- {
- int i;
- char temp[3];
- if(unx==NULL || string==NULL)
- return;
-
- for(i=0;i<16;i++)
- {
- if(i==0)
- {
- sprintf(temp,"%02x",unx[i]);
- strcpy(string,temp);
- }
- else
- {
- sprintf(temp,"%02x",unx[i]);
- strcat(string,temp);
- }
- }
- }
- static void MDFile(const char *filename,char *store)
- {
- FILE *fd;
- char buffer[120];
- struct stat buf;
- int size;
- int blocknum;
- int resize;
- int i;
-
- unsigned char digest[16];
- MD5_CTX context;
-
- if(lstat(filename,&buf)<0)
- {
- printf("stat file error: %s/n",filename);
- exit(1);
- }
- if(buf.st_size==0)
- size=buf.st_size;
- else
- size=buf.st_size-1;
-
- if((fd=fopen(filename,"r+"))==NULL)
- {
- printf("open file: %s error/n",filename);
- exit(1);
- }
-
- MD5Init(&context);
-
- if(size<=120)
- {
- fread(buffer,size,1,fd);
- MD5Update(&context,buffer,size);
- MD5Final(digest,&context);
- fclose(fd);
- }
- else
- {
- blocknum=size/120;
- resize=size-blocknum*120;
- for(i=0;i<blocknum;i++)
- {
- fread(buffer,120,1,fd);
- MD5Update(&context,buffer,120);
- }
-
- fread(buffer,resize,1,fd);
- MD5Update(&context,buffer,resize);
- MD5Final(digest,&context);
- fclose(fd);
- }
-
-
- md5_to_string(digest,store);
- #ifdef _DEBUG_MESSAGE_
- MDPrint(digest);
- printf("/nin md5 file store is:%s/n",store);
-
- #endif
-
- }
- void
- init_stack(str_dir *std)
- {
- std->top=-1;
- }
- void
- pushchar(str_dir *std,char *ar )
- {
- if(std->top>=STACK_SIZE-1)
- {
- printf("stack is full/n");
- exit(0);
- }
- if(std->top<0)
- strcpy(std->file_dir,ar);
- else
- strcat(std->file_dir,ar);
- std->top+=strlen(ar);
- std->file_dir[std->top+1]='/0';
- }
- void
- popchar(str_dir *std,int num)
- {
- if (std->top==-1)
- {
- printf("stack is null/n");
- exit(0);
- }
- char buf[STACK_SIZE];
- strcpy(buf,std->file_dir);
- memset(std->file_dir,0,strlen(std->file_dir));
- memcpy(std->file_dir,buf,std->top-num+1);
- std->top-=num;
- std->file_dir[std->top+1]='/0';
- }
- void
- trave_dir(char *dirname, str_dir *std,FILE *fd)
- {
- DIR * dp;
- struct dirent * entry;
- struct stat statbuf;
- if ((dp=opendir(dirname))==NULL)
- {
- printf("can't open directory:%s/n",dirname);
-
- exit(1);
- }
- #ifdef _DEBUF_MESSAGE_
- char pwd[60];
- getcwd(pwd,60);
- printf("before chdir dir is: %s/n",pwd);
- #endif
-
- chdir(dirname);
- #ifdef _DEBUG_MESSAGE_
- getcwd(pwd,60);
- printf("after chdir dir is: %s/n",pwd);
- #endif
- while ((entry=readdir(dp))!=NULL)
- {
- if(strcmp(entry->d_name,"netpower")==0)
- continue;
- lstat(entry -> d_name,&statbuf);
- if (S_ISREG(statbuf.st_mode))
- {
-
- md5_arc *md5h;
- md5h=(md5_arc *)malloc(sizeof(md5_arc));
-
- pushchar(std,"/");
- pushchar(std,entry->d_name);
-
- strcpy(md5h->dirname,std->file_dir);
-
- MDFile(entry->d_name,md5h->md5string);
-
- fprintf(fd,"%s ",md5h->md5string);
- fprintf(fd,"%s/n",md5h->dirname);
- #ifdef _DEBUG_MESSAGE_
- printf("%s/n",std->file_dir);
- #endif
- popchar(std,strlen(entry->d_name)+1);
-
-
- }
- else if(S_ISDIR(statbuf.st_mode))
- {
- if (strcmp(".",entry -> d_name)==0||strcmp("..",entry -> d_name)==0)
- continue;
- pushchar(std,"/");
- pushchar(std,entry->d_name);
- trave_dir(entry->d_name,std,fd);
- popchar(std,strlen(entry->d_name)+1);
- }
- else
- continue;
- }
- chdir("..");
-
- closedir(dp);
- #ifdef _DEBUG_MDSSAGE_
- char pwd2[60];
- getcwd(pwd2,60);
- printf("after read dir is: %s/n",pwd2);
- #endif
- }
- void
- readchar(FILE *fd,char *store,char end)
- {
- char buf1[16];
- unsigned char buf2[16];
- char b;
- int i=0;
- while((b=fgetc(fd))!=end)
- {
- if(feof(fd))
- return;
- store[i]=b;
- i++;
- }
- store[i]='/0';
-
-
- }
- void
- creat_md5sums(char *dirname,char *md5file)
- {
- FILE *fd;
- if((fd=fopen(md5file,"a+"))==NULL)
- {
- printf("open file error/n");
- exit(1);
- }
- str_dir *std;
- std=(str_dir *)malloc(sizeof(str_dir));
- init_stack(std);
- pushchar(std,dirname);
-
- trave_dir(dirname,std,fd);
- free(std);
- fclose(fd);
-
- }
- int
- check(char *md5file)
- {
- FILE *fd;
- char md5string[32];
- char filedir[STACK_SIZE];
- char checkstring[32];
- char buf[STACK_SIZE];
- int flag=1;
- #ifdef _DEBUG_MESSAGE
- printf("md5file :%s/n",md5file);
- #endif
-
- if((fd=fopen(md5file,"r"))==NULL)
- {
- printf("open md5sums error/n");
- }
- while(!feof(fd))
- {
- readchar(fd,md5string,' ');
- readchar(fd,filedir,'/n');
- if(feof(fd))
- break;
- strcpy(buf,filedir);
- MDFile(filedir,checkstring);
- if(strcmp(md5string,checkstring)==0)
- printf("check file: %s ......yes/n",buf);
- if(strcmp(md5string,checkstring)!=0)
- {
- printf("check file: %s ......no/n",buf);
- flag=0;
- }
- }
- fclose(fd);
- return flag;
- }