MD5算法实现

什么是MD5???---MD5的全称是Message-Digest Algorithm 5

 MD5的典型应用是对一段信息(Message)产生信息摘要(Message-Digest),以防止被篡改。比如,在UNIX下有很多软件在下载的时候都有一个文件名相同,文件扩展名为.md5的文件,在这个文件中通常只有一行文本,大致结构如:

 MD5 (tanajiya.tar.gz) = 0ca175b9c0f726a831d895e269332461

 这就是tanajiya.tar.gz文件的数字签名。MD5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的MD5信息摘要。如果在以后传播这个文件的过程中,无论文件的内容发生了任何形式的改变(包括人为修改或者下载过程中线路不稳定引起的传输错误等),只要你对这个文件重新计算MD5时就会发现信息摘要不相同,由此可以确定你得到的只是一个不正确的文件。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的 "抵赖",这就是所谓的数字签名应用。

MD5还广泛用于加密和解密技术上。比如在UNIX系统中用户的密码就是以MD5(或其它类似的算法)经加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成MD5值,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。

/*

 md5.c

 this is for encryt by md5,just simple implement it.

 注释:可以使用,和百度百科的最后结果相同

 来源:http://www.linuxidc.com/Linux/2012-07/65941.htm

 时间:2014.12.19

 原理:1填充:将数据填充为N*512+448(即N*64+56)

         2算法计算,将 A->a,a经FF,GG,HH,II计算,A=A+a

         3将计算后的各块级联生成128位的加密算法

*/ 

 

#include <stdio.h>  

#include <string.h>  

//#include "md5.h"   头文件已经加到程序中

 

#ifndef MD5_FORENCRPTY_H  

#define MD5_FORENCRPTY_H  

/*this is only 32bit*/ 

typedef unsigned int md5_int; 

struct MD5_struct 

    md5_int A; 

    md5_int B; 

    md5_int C; 

    md5_int D; 

    md5_int lenbuf;     

    char buffer[128]; 

}; 

void md5_init(struct MD5_struct *ctx,char * buffer); 

void md5_process(struct MD5_struct * ctx); 

char * md5_fini(struct MD5_struct *ctx,void *rebuf); 

void md5_buffer_full(struct MD5_struct * ctx); 

void md5_print(struct MD5_struct * ctx); 

#endif 

 

struct MD5_struct ctx; 

/* 

extern void md5_init(struct MD5_struct *ctx,char * buffer); 

extern void md5_process(struct MD5_struct * ctx); 

extern char * md5_fini(struct MD5_struct *ctx,void * rebuf); 

extern void md5_buffer_full(struct MD5_struct * ctx); 

extern void md5_print(struct MD5_struct * ctx); 

*/

/* set data for fill buffer */ 

md5_int fullbuffer[64]={0x80,0}; 

md5_int M[16]={0,0}; 

 

/*

 for loop A\B\C\D ways

*/ 

#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 ROT(x,s) (x=(x<<s)|(x>>(32-s)))  

 

#define FF(a,b,c,d,j,s,T) {a=a+(F(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}  

#define GG(a,b,c,d,j,s,T) {a=a+(G(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}  

#define HH(a,b,c,d,j,s,T) {a=a+(H(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}  

#define II(a,b,c,d,j,s,T) {a=a+(I(b,c,d)+M[j]+T);ROT(a,s);a=a+b;}  

 

/*

 init MD5_struct ctx

*/ 

void md5_init(struct MD5_struct *ctx,char * buffer) 

    ctx->A=0x67452301;//一个四个字的缓冲器(A,B,C,D)来计算报文摘要 

    ctx->B=0xefcdab89; 

    ctx->C=0x98badcfe; 

    ctx->D=0x10325476; 

    ctx->lenbuf=strlen(buffer); 

    memcpy(ctx->buffer,buffer,ctx->lenbuf);

    //memcpy(void*dest,constvoid*src,size_tcount)

     

 

/*

 print ctx's message 

*/ 

void md5_print(struct MD5_struct *ctx) 

    printf("******************************\n"); 

    printf("ctx->A:%x\n",ctx->A); 

    printf("ctx->B:%x\n",ctx->B); 

    printf("ctx->C:%x\n",ctx->C); 

    printf("ctx->D:%x\n",ctx->D); 

    printf("ctx->lenbuf:%d\n",ctx->lenbuf); 

    printf("ctx->buffer:%s\n",ctx->buffer); 

    printf("\n\r************print******************\n"); 

 

 

/*

 fill buffer to mod%64

*/ 

void md5_buffer_full(struct MD5_struct *ctx) 

    md5_int sizebyte[2]={0,0}; 

    md5_int len=ctx->lenbuf; 

    md5_int byte=len>56?(64-(len-56)):56-len; 

    memcpy(&ctx->buffer[len],fullbuffer,byte); 

    sizebyte[0]+=(ctx->lenbuf<<3); 

    if(sizebyte[0]<ctx->lenbuf) 

        sizebyte[1]++; 

 

    memcpy(&ctx->buffer[len+byte],&sizebyte,sizeof(sizebyte));    

     

/*

 deal message

*/ 

void md5_process(struct MD5_struct *ctx) 

    int i=0; 

    int j; 

    md5_int a=ctx->A; 

    md5_int b=ctx->B; 

    md5_int c=ctx->C; 

    md5_int d=ctx->D; 

    for(i=0;i<=ctx->lenbuf;i+=64)//loop time  

    { 

        memcpy(M,ctx->buffer,sizeof(md5_int)*16); 

 

        /* round 1 */ 

        FF(a,b,c,d, 0, 7,0xd76aa478);  

        FF(d,a,b,c, 1,12,0xe8c7b756);  

        FF(c,d,a,b, 2,17,0x242070db); 

        FF(b,c,d,a, 3,22,0xc1bdceee);  

        FF(a,b,c,d, 4, 7,0xf57c0faf);  

        FF(d,a,b,c, 5,12,0x4787c62a);  

        FF(c,d,a,b, 6,17,0xa8304613);  

        FF(b,c,d,a, 7,22,0xfd469501);  

        FF(a,b,c,d, 8, 7,0x698098d8);  

        FF(d,a,b,c, 9,12,0x8b44f7af);  

        FF(c,d,a,b,10,17,0xffff5bb1);  

        FF(b,c,d,a,11,22,0x895cd7be); 

        FF(a,b,c,d,12, 7,0x6b901122);  

        FF(d,a,b,c,13,12,0xfd987193);  

        FF(c,d,a,b,14,17,0xa679438e);  

        FF(b,c,d,a,15,22,0x49b40821); 

 

        /* round 2 */ 

        GG(a,b,c,d, 1, 5,0xf61e2562); 

        GG(d,a,b,c, 6, 9,0xc040b340); 

        GG(c,d,a,b,11,14,0x265e5a51);  

        GG(b,c,d,a, 0,20,0xe9b6c7aa);  

        GG(a,b,c,d, 5, 5,0xd62f105d);  

        GG(d,a,b,c,10, 9,0x02441453);  

        GG(c,d,a,b,15,14,0xd8a1e681);  

        GG(b,c,d,a, 4,20,0xe7d3fbc8);  

        GG(a,b,c,d, 9, 5,0x21e1cde6);  

        GG(d,a,b,c,14, 9,0xc33707d6);  

        GG(c,d,a,b, 3,14,0xf4d50d87);  

        GG(b,c,d,a, 8,20,0x455a14ed);  

        GG(a,b,c,d,13, 5,0xa9e3e905);    

        GG(d,a,b,c, 2, 9,0xfcefa3f8);  

        GG(c,d,a,b, 7,14,0x676f02d9);  

        GG(b,c,d,a,12,20,0x8d2a4c8a); 

 

        /* round 3 */ 

        HH(a,b,c,d, 5, 4,0xfffa3942);  

        HH(d,a,b,c, 8,11,0x8771f681);  

        HH(c,d,a,b,11,16,0x6d9d6122);  

        HH(b,c,d,a,14,23,0xfde5380c);  

        HH(a,b,c,d, 1, 4,0xa4beea44);  

        HH(d,a,b,c, 4,11,0x4bdecfa9);  

        HH(c,d,a,b, 7,16,0xf6bb4b60);  

        HH(b,c,d,a,10,23,0xbebfbc70);  

        HH(a,b,c,d,13, 4,0x289b7ec6);  

        HH(d,a,b,c, 0,11,0xeaa127fa);  

        HH(c,d,a,b, 3,16,0xd4ef3085);  

        HH(b,c,d,a, 6,23,0x04881d05);  

        HH(a,b,c,d, 9, 4,0xd9d4d039);  

        HH(d,a,b,c,12,11,0xe6db99e5); 

        HH(c,d,a,b,15,16,0x1fa27cf8);  

        HH(b,c,d,a, 2,23,0xc4ac5665); 

 

        /* round 4 */ 

        II(a,b,c,d, 0, 6,0xf4292244);  

        II(d,a,b,c, 7,10,0x432aff97);  

        II(c,d,a,b,14,15,0xab9423a7);  

        II(b,c,d,a, 5,21,0xfc93a039);  

        II(a,b,c,d,12, 6,0x655b59c3);  

        II(d,a,b,c, 3,10,0x8f0ccc92);  

        II(c,d,a,b,10,15,0xffeff47d);  

        II(b,c,d,a, 1,21,0x85845dd1);  

        II(a,b,c,d, 8, 6,0x6fa87e4f);  

        II(d,a,b,c,15,10,0xfe2ce6e0);  

        II(c,d,a,b, 6,15,0xa3014314);  

        II(b,c,d,a,13,21,0x4e0811a1);  

        II(a,b,c,d, 4, 6,0xf7537e82);  

        II(d,a,b,c,11,10,0xbd3af235);  

        II(c,d,a,b, 2,15,0x2ad7d2bb);  

        II(b,c,d,a, 9,21,0xeb86d391); 

 

        ctx->A+=a; 

        ctx->B+=b; 

        ctx->C+=c; 

        ctx->D+=d; 

 

    } 

 

 

/*

 store result

*/ 

char * md5_fini(struct MD5_struct *ctx,void *rebuf) 

    int i=0; 

    memset(rebuf,0,16); 

    memcpy(&((unsigned char *)rebuf)[0],&ctx->A,sizeof(ctx->A)); 

    memcpy(&((unsigned char *)rebuf)[4],&ctx->B,sizeof(ctx->B)); 

    memcpy(&((unsigned char *)rebuf)[8],&ctx->C,sizeof(ctx->C)); 

    memcpy(&((unsigned char *)rebuf)[12],&ctx->D,sizeof(ctx->D)); 

    /* print md5 result */ 

    md5_print(ctx); 

    printf("md5:"); 

    while(i<16) 

    { 

        printf("%02x",((unsigned char *)rebuf)[i++]); 

    } 

        printf("\n*****nj****************************\n"); 

    return rebuf; 

int main(int argc,char ** argv) 

    unsigned char rebuf[16]; 

    unsigned char message[64]; 

    printf("please enter you message for encrypt:"); 

    scanf("%s",message); 

    md5_init(&ctx,message); 

    md5_buffer_full(&ctx); 

    md5_process(&ctx); 

    md5_fini(&ctx,rebuf); 

    return 0; 

}  

转载于:https://www.cnblogs.com/zhouhbing/p/4173223.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/545551.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle plsqlI 练习 传值

--根据人名查个人薪水和本部门平均薪水--select语句实现select a.deptno "部门编号",a.dname "部门名称",a.ename "姓名",a.sal "薪水",b.avg_sal "部门平均薪水"from (select d.deptno, d.dname, e.ename, sal n…

Java StringBuilder codePointBefore()方法与示例

StringBuilder类codePointBefore()方法 (StringBuilder Class codePointBefore() method) codePointBefore() method is available in java.lang package. codePointBefore()方法在java.lang包中可用。 codePointBefore() method is used to represent the Unicode code point …

MySQL 中锁的面试题总结

什么是锁?MySQL 中提供了几类锁? 锁是实现数据库并发控制的重要手段,可以保证数据库在多人同时操作时能够正常运行。MySQL 提供了全局锁、行级锁、表级锁。其中 InnoDB 支持表级锁和行级锁,MyISAM 只支持表级锁。 什么是死锁? 是指两个或两个以上的进程在执行过程中,因…

Oracle-(if/case/以及模拟注册登录)练习-20131015

--作业--1、 输入部门编号&#xff0c;按照下列加薪比例执行&#xff08;用if-elsif 和case两种方法实现&#xff09;。--deptno raise(%)--10 5%--20 10%--30 15%--40 20%--加薪比例以现有的sal为标准--方法一select deptno,ename,sal,(case deptnowhen 10 then sal * 0…

大二上数据结构复习2

第二章线性表 综合 一、在什么情况下用顺序表比用链表好 表长度确定&#xff0c;很少进行插入删除操作且经常访问元素 二、2-4 顺序表的插入和删除要求仍然保持各个元素原来的次序。设在等概率情形下, 对有 127 个元素的顺序表进行插入, 平均需要移动多少个元素? 删除一个元素…

Java SimpleTimeZone inDaylightTime()方法及示例

SimpleTimeZone类inDaylightTime()方法 (SimpleTimeZone Class inDaylightTime() method) inDaylightTime() method is available in java.util package. inDaylightTime()方法在java.util包中可用。 inDaylightTime() method is used to check whether the given date (d) is …

MySQL 命令和内置函数

如何用命令行方式连接 MySQL 数据库? 使用 mysql -u用户名 -p密码; 输入用户名和密码就可以正常进入数据库连接了,实例如下: mysql -uroot -p123456; 其中,用户名为 root,密码为 123456。 关于命令 mysql -h 127.0.0.1 -uroot -P 3307 -p3307 以下说法错误的是? A.-h …

Oracle plsql 月历

declarev_year number : 2013;v_month number : &input_month;v_day number;v_lastday number;begindbms_output.put_line(v_year || 年 || v_month || 月的月历);--转换星期为数字&#xff0c;方便计算case substr(to_char(to_date(v_year || v_month,yyyymm),day),3,1)wh…

Java GregorianCalendar setTimeZone()方法与示例

GregorianCalendar类setTimeZone()方法 (GregorianCalendar Class setTimeZone() method) setTimeZone() method is available in java.util package. setTimeZone()方法在java.util包中可用。 setTimeZone() method is used to sets the time zone with the specified TimeZon…

操作系统(王道笔记第二章)

目录第二章 2.1_1进程的定义、组成、组成形式、特征 2.1_2进程的状态与转换 2.1_3进程的控制 2.1_4进程通信 2.1_5线程概念和多线程模型 2.2_1处理机调度的概念层次 2.2_2处理机调度的时机、切换与过程、方式 2.2_3调度算法的评价指标 2.2_4FCFS、SJF、HRRN调度算法 2.2_5时间片…

MySQL 中日志的面试题总结

MySQL 有哪些重要的日志文件? MySQL 中的重要日志分为以下几个: ① 错误日志:用来记录 MySQL 服务器运行过程中的错误信息,比如,无法加载 MySQL 数据库的数据文件,或权限不正确等都会被记录在此,还有复制环境下,从服务器进程的信息也会被记录进错误日志。默认情况下,…

centos不能挂在ntfs

roots 下载]# mount /dev/sdb1 /mnt mount: unknown filesystem type ntfs wget http://www.tuxera.com/community/ntfs-3g-download/ http://tuxera.com/opensource/ntfs-3g_ntfsprogs-2014.2.15.tgz 下载&#xff0c;安装 ./configure make make install 用法&#xff1a; mo…

Oracle 练习题 20131017

--2013-10-17 练习题--1、输入一个年份&#xff0c;判断其是不是闰年&#xff0c;并做相应的提示。--方法一&#xff1a;正常算declarev_year number : 1900;beginif mod(v_year,100) 0 thenif mod(v_year,400) 0 thendbms_output.put_line(v_year || 是闰年);elsedbms_outpu…

Java类类getDeclaredMethod()方法及示例

类的类getDeclaredMethod()方法 (Class class getDeclaredMethod() method) getDeclaredMethod() method is available in java.lang package. getDeclaredMethod()方法在java.lang包中可用。 getDeclaredMethod() method is used to return Method objects that indicate the …

MySQL 常见的开放性问题

有一个超级大表,如何优化分页查询? 超级大表的分页优化分有以下两种方式: 数据库层面优化:利用子查询优化超多分页场景,比如:SELECT a.* FROM 表 1 a, (select id from 表 1 where 条件 LIMIT 100000,20 ) b where a.id=b.id ,先快速定位需要获取的 id 段,然后再关联查…

C语言画图形(图形库graphics的使用)

目录 工具 c语言基本绘图 文字输出 c语言基本贴图 获取鼠标、键盘信息 工具 &#xff08;1&#xff09;环境&#xff1a;VC &#xff08;2&#xff09;库函数&#xff1a;graphics.h&#xff08;因为不是标准库函数&#xff0c;所以需下载EASYX&#xff09; &#xff08;3&am…

关于DDD中Domain的思考

2019独角兽企业重金招聘Python工程师标准>>> 本文既不推销UML&#xff0c;也不推广DDD&#xff0c;更不涉及各种论战。-- 作者 某天又一次打开关于DDD(领域驱动设计)的PDF文档时&#xff0c;自己有了个疑问&#xff1a;什么是领域(Domain)&#xff1f;译文中是这样描…

Oracle plsql 计算日期间工作日天数

declarev_fdate date : to_date(2013-10-4,yyyy-mm-dd);v_ldate date : to_date(2013-10-22,yyyy-mm-dd);v_interval_a number;v_interval_b number;v_interval_all number;begin--先算整周有几周&#xff0c;然后乘一周五天工作日v_interval_a : floor((v_ldate - v_fdate)/7)…

MySQL 性能优化 分布式

MySQL 性能指标都有哪些?如何得到这些指标? MySQL 的性能指标如下: ① TPS(Transaction Per Second) 每秒事务数,即数据库每秒执行的事务数。 MySQL 本身没有直接提供 TPS 参数值,如果我们想要获得 TPS 的值,只有我们自己计算了,可以根据 MySQL 数据库提供的状态变…

Java Collections CheckedCollection()方法与示例

集合类的checkedCollection()方法 (Collections Class checkedCollection() method) checkedCollection() Method is available in java.lang package. DrawnCollection()方法在java.lang包中可用。 checkedCollection() Method is used to return the typesafe view of the gi…