近日要用到文件校验算法,查看了一下相关资料,得到以下理论与实践经验.一.理论部分:1.预备知识1.1什么是数据校验通俗的说,就是为保证数据的完整性,用一种指定的算法对原始数据计算出的一个校验值.接收方用同样的算法计算一次校验值,如果与随数据提供的校验值一样,就说明数据是完整的.1.2最简单的检验实现方法:最简单的校验就是把原始数据与待比较数据直接进行比较,看是否完全一样这种方法是最安全最准确的.同时也是效率最低的.适用范围:简单的数据量极小的通讯.应用例子:龙珠cpu在线调试工具bbug.exe.它与龙珠cpu间通讯时,bbug发送一个字节cpu返回收到的字节,bbug确认是刚才发送字节后才继续发送下一个字节的.1.3奇偶校验parity check实现方法:在数据存储与传输中,字节中额外增加一个比特位,用来检验错误.校验位可以通过数据位异或计算出来.应用例子:单片机串口通讯有一模式就是8位数据通讯,另加第9位用于放校验值.1.4 bcc异或校验法(block check character)实现方法:很多基于串口的通讯都用这种既简单又相当准确的方法.它就是把所有数据都与一个指定的初始值(通常是0)异或一次,最后的结果就是校验值,通常把她附在通讯数据的最后一起发送出去.接收方收到数据后自己也计算一次异或与校验值,如果与收到的校验值一致就说明收到的数据是完整的.校验值计算的代码类似于:unsigned ucrc=0;//校验初始值for(int i=0;i<datalenth;i++) ucrc^=data[i];适用范围:适用于大多数要求不高的数据通讯.应用例子:ic卡接口通讯.很多单片机系统的串口通讯都使用.1.5 crc循环冗余校验(cyclic redundancy check)实现方法:这是利用除法及余数的原理来进行错误检测的.将接收到的码组进行除法运算,如果除尽,则说明传输无误;如果未除尽,则表明传输出现差错.crc校验具还有自动纠错能力.crc检验主要有计算法与查表法两种方法,网上很多实现代码. 适用范围:crc-12码通常用来传送6-bit字符串;crc-16及crc-ccitt码则用是来传送8-bit字符.crc-32:硬盘数据,网络传输等应用例子:rar,以太网卡芯片.mpeg解码芯片中1.6 md5校验与数字签名实现方法:主要有md5与des算法.适用范围:数据比较大或要求比较高的场合.如md5用于大量数据.文件校验,des用于保密数据的校验(数字签名)等等.应用例子:文件校验.银行系统的交易数据
二.实现方法 由于此处的文件校验用到要求比较高的场合,故采用了方法6,md5校验算法,从codeguru下载了一个md5校验算法的实现模块,加入自己要校验的文件名,实现完成.下面具体描述一下实现过程:1.创建一个简单的对话框程序;2.设置cstring类型的变量m_filename与m_strfilechecksum以存放要校验的文件名与校验与;3.在对话框类中创建checksumselectedfile()函数,调用md5校验与类(附录中有其实现文件)中的getmd5计算文件校验与.4.使用定时器定时巡检该文件的校验与,一旦发现校验与发生变化,立刻出现提示.三.附录(md5算法实现的源码)以下代码实现均来自www.codeguru.com.1.md5checksumdefines.h(定义相关常量的头文件)//magic initialization constants#define md5_init_state_0 0x67452301#define md5_init_state_1 0xefcdab89#define md5_init_state_2 0x98badcfe#define md5_init_state_3 0x10325476 【程序编程相关:Socket中如何设置连接超时】
2.具体的实现理论2.1 算法概述md5算法是md4算法的改进算法.ron rivest 于1990年提出md4单向散列函数,md表示消息摘要(message digest),对输入消息,算法产生128位散列值.该算法首次公布之后,bert den boer与antoon bosselaers 对算法三轮中的后两轮进行了成功的密码分析.在一个不相关的分析结果中,ralph merkle成功地攻击了前两轮.尽管这些攻击都没有扩展到整个算法,但rivest还是改进了其算法,结果就是md5算法. md5算法是md4的改进算法,它比md4更复杂,但设计思想相似,输入的消息可任意长,输出结果也仍为128位,特别适用于高速软件实现,是基于32-位操作数的一些简单的位操作.2.2 算法步骤l 将输入消息按512-位分组,最后要填充成为512位的整数倍,且最后一组的后64位用来填充消息长度(填充前).填充方法为附一个1在消息后,后接所要求的多个0.这样可以确保不同消息在填充后不相同.l 由于留出64位用来表示消息长度,那么消息的长度最多可达264字节,相当于4g×4g字节,文件的长度是不可能达到这么大,因此通常都是只采用64位中的低32位来表示消息长度,高32位填充0.l 初始化md变量.由于每轮输出128位,这128位可用下面四个32位字a,b,c,d来表示.其初始值设为:a=0x01234567b=0x89abcdefc=0xfedcba98d=0x76543210l 开始进入算法主循环,循环的次数是消息中512位消息分组的数目.先将上面a.b.c.d四个变量分别复制到另外四个变量a.b.c.d中去.主循环有四轮,每轮很相似.每轮进行16次操作,每次操作对a.b.c.d四个变量中的三个作一次非线性函数运算,然后将所得结果加上第四个变量,消息的一个子分组与一个常数.再将所得结果向右环移一个不定的数,并加上a,b,c或d中之一.最后用该结果取代a,b,c或d中之一.以下是每次操作中用到的四个非线性函数(每轮一个).f(x,y,z)=(x∧y)∨(( x)∧z)g(x,y,z)=(x∧z)∨(y∧( z))h(x,y,z)=x⊕y⊕zi(x,y,z)=y⊕(x∨( z))其中,⊕是异或,∧是与,∨是或, 是反符号.这些函数是这样设计的:如果x.y与z的对应位是独立与均匀的,那么结果的每一位也应是独立与均匀的.函数f是按逐位方式操作:如果x,那么y,否则z.函数h是逐位奇偶操作符.设mj表示消息的第j个子分组(从0到15),<<<s表示循环左移s,则四种操作为:ff(a,b,c,d,mj,s,ti)表示a = b+((a+f(b,c,d)+ mj + ti)<<<s)gg(a,b,c,d,mj,s,ti)表示a = b+((a+g(b,c,d)+ mj + ti)<<<s)hh(a,b,c,d,mj,s,ti)表示a = b+((a+h(b,c,d)+ mj + ti)<<<s)ii(a,b,c,d,mj,s,ti)表示a = b+((a+i(b,c,d)+ mj + ti)<<<s)四轮(64步)结果略.注:常数ti的选择:第i步中,ti是232 ×abs (sin(i))的整数部分,i的单位是弧度.所有这些完成之后,将a,b,c,d分别加上a,b,c,d.然后用下一分组数据继续运行算法,最后的输出是a,b,c与d的级联.l 最后得到的a,b,c,d就是输出结果,a是低位,d为高位,dcba组成128位输出结果.2.3 md5的安全性ron rivest概述了md5安全性[8]:l 与md4相比,增加了第四轮.l 每一步均有唯一的加法常数.l 为减弱第二轮中函数g的对称性从((x∧y) ∨(x∧z) ∨(y∧z))变为((x∧z) ∨(y∧( z))).l 每一步加上了上一步的结果,引起更快的雪崩效应.l 改变了第二轮与第三轮中访问消息子分组的次序,使其形式更不相似.l 近似优化了每一轮中的循环左移位移量以实现更快的雪崩效应.各轮的位移量互不相同.从安全角度讲,md5的输出为128位,若采用纯强力攻击寻找一个消息具有给定hash值的计算困难性为2128,用每秒可试验1 000 000 000个消息的计算机需时1.07×1022年.若采用生日攻击法,寻找有相同hash值的两个消息需要试验264个消息,用每秒可试验1 000 000 000个消息的计算机需时585年. 【推荐阅读:C++/CLI语言的属性探索】
... 下一页