RFC1321MD5信息摘要算法

上传人:沈*** 文档编号:66133839 上传时间:2022-03-26 格式:DOC 页数:19 大小:110.50KB
返回 下载 相关 举报
RFC1321MD5信息摘要算法_第1页
第1页 / 共19页
RFC1321MD5信息摘要算法_第2页
第2页 / 共19页
RFC1321MD5信息摘要算法_第3页
第3页 / 共19页
点击查看更多>>
资源描述
RFC1321The MD5 Message-Digest Algorithm MD5 报文摘要算法组织:中国互动出版网(http:/www.china-RFC文档中文翻译计划(http:/www.china-E-mail:ouyangchina-译者:()译文发布时间:2001-11-7版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须保留本文档的翻译及版权信息。Network Working Group R. RivestRequest for Comments: 1321 MIT Laboratory for Computer Science and RSA Data Security, Inc. April 1992MD5 报文摘要算法(RFC1321The MD5 Message-Digest Algorithm)本文地位本文并非指定一个Internet标准,而是向互联网提供信息,本文可以任意传播,不受限制。致谢Don Coppersmith, Burt Kaliski, Ralph Merkle,David Chaum, 和Noam Nisan向本文提供极大的帮助,在此本人表示忠心的感谢。目录1执行简介12术语和符号13MD5算法描述24摘要45MD4和MD5的区别46参考文献47附录A参考应用程序48安全事项189作者地址181 执行简介本文描述了MD5报文摘要算法,此算法将对输入的任意长度的信息进行计算,产生一个128位长度的“指纹”或“报文摘要”,假定两个不同的文件产生相同的报文摘要或由给定的报文摘要产生原始信息在计算上是行不通的。MD5算法适合用在数据签名应用中,在此应用中,一个大的文件必须在类似RSA算法的公用密钥系统中用私人密钥加密前被“压缩”在一种安全模式下。MD5算法能在32位机器上能以很快的速度运行。另外,MD5算法不需要任何大型的置换列表。此算法编码很简洁。MD5 算法是MD4报文摘要算法的扩展。MD5算法稍慢于MD4算法,但是在设计上比MD4算法更加“保守”。设计MD5是因为MD4算法被采用的速度太快,以至于还无法证明它的正确性,因为MD4算法速度非常快,它处在遭受成功秘密攻击的“边缘”。MD5后退了一步,它舍弃了一些速度以求更好的安全性。它集中了不同的评论家提出的建议,并采取了一些附加的优化措施。它被放在公共的地方以求公众的评论意见,它可能当作一个标准被采纳。作为基于OSI的应用,MD5的对象标识符是:md5 OBJECT IDENTIFIER :=iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5 在X.509类型AlgorithmIdentifier 3中,MD5算法参数应该包括NULL类型。2 术语和符号本文中一个“字”是32位,一个“字节”是8位。一系列位串可看成是一系列字节的普通形式,其中的连续的8位看成一个字节,高位在前,同理一系列字节串可看成是一系列32位的字,其中每个连续的4个字节当作一个字,地位在前。我们定义x_i代表“x减去I”.如果下划线左边的是一个表达式,则用括号括住,如:x_i+1。同样我们用代表求幂,这样xi则代表x的i次幂。符号“”代表字的加,X s代表32位的值X循环左移s位,not(X)代表X的按位补运算,X v Y 表示X和Y的按位或运算,XxorY代表X和Y的按位异或运算,XY代表X和Y的按位与运算。3 MD5算法描述我们假设有一个b位长度的输入信号,希望产生它的报文摘要,此处b是一个非负整数,b也可能是0,不一定必须是8的整数倍,它可能是任意大的长度。我们设想信号的比特流如下所示: m_0 m_1 . m_b-1下面的5步计算信息的报文摘要。(1) 补位MD5算法是对输入的数据进行补位,使得如果数据位长度LEN对512求余的结果是448。即数据扩展至K*512+448位。即K*64+56个字节,K为整数。补位操作始终要执行,即使数据长度LEN对512求余的结果已是448。具体补位操作:补一个1,然后补0至满足上述要求。总共最少要补一位,最多补512位。(2) 补数据长度用一个64位的数字表示数据的原始长度b,把b用两个32位数表示。那么只取B的低64位。当遇到b大于264这种极少遇到的情况时,这时,数据就被填补成长度为512位的倍数。也就是说,此时的数据长度是16个字(32位)的整数倍数。用M0 . N-1表示此时的数据,其中的N是16的倍数。(3) 初始化MD缓冲器用一个四个字的缓冲器(A,B,C,D)来计算报文摘要,A,B,C,D分别是32位的寄存器,初始化使用的是十六进制表示的数字A=0X01234567B=0X89abcdefC=0Xfedcba98D=0X76543210 (4) 处理位操作函数首先定义4个辅助函数,每个函数的输入是三个32位的字,输出是一个32位的字。X,Y,Z为32位整数。 F(X,Y,Z) = XY v not(X) Z G(X,Y,Z) = XZ v Y not(Z) H(X,Y,Z) = X xor Y xor Z I(X,Y,Z) = Y xor (X v not(Z)这一步中使用一个64元素的常数组T1 . 64,它由sine函数构成,Ti表示数组中的第i个元素,它的值等于经过4294967296次abs(sin(i)后的值的整数部分(其中i是弧度 )。Ti为32位整数用16进制表示,数组元素在附录中给出。具体过程如下: /* 处理数据原文 */For i = 0 to N/16-1 do /*每一次,把数据原文存放在16个元素的数组X中. */For j = 0 to 15 doSet Xj to Mi*16+j.end/结束对J的循环/* Save A as AA, B as BB, C as CC, and D as DD. */AA = ABB = BCC = CDD = D /* 第1轮*/* 以 abcd k s i表示如下操作a = b + (a + F(b,c,d) + Xk + Ti) s). */* Do the following 16 operations. */ABCD 0 7 1 DABC 1 12 2 CDAB 2 17 3 BCDA 3 22 4ABCD 4 7 5 DABC 5 12 6 CDAB 6 17 7 BCDA 7 22 8ABCD 8 7 9 DABC 9 12 10 CDAB 10 17 11 BCDA 11 22 12ABCD 12 7 13 DABC 13 12 14 CDAB 14 17 15 BCDA 15 22 16 /* 第2轮* */* 以 abcd k s i表示如下操作a = b + (a + G(b,c,d) + Xk + Ti) s). */* Do the following 16 operations. */ABCD 1 5 17 DABC 6 9 18 CDAB 11 14 19 BCDA 0 20 20ABCD 5 5 21 DABC 10 9 22 CDAB 15 14 23 BCDA 4 20 24ABCD 9 5 25 DABC 14 9 26 CDAB 3 14 27 BCDA 8 20 28ABCD 13 5 29 DABC 2 9 30 CDAB 7 14 31 BCDA 12 20 32 /* 第3轮*/* 以 abcd k s i表示如下操作a = b + (a + H(b,c,d) + Xk + Ti) s). */* Do the following 16 operations. */ABCD 5 4 33 DABC 8 11 34 CDAB 11 16 35 BCDA 14 23 36ABCD 1 4 37 DABC 4 11 38 CDAB 7 16 39 BCDA 10 23 40ABCD 13 4 41 DABC 0 11 42 CDAB 3 16 43 BCDA 6 23 44ABCD 9 4 45 DABC 12 11 46 CDAB 15 16 47 BCDA 2 23 48 /* 第4轮*/* 以 abcd k s i表示如下操作a = b + (a + I(b,c,d) + Xk + Ti) s). */* Do the following 16 operations. */ABCD 0 6 49 DABC 7 10 50 CDAB 14 15 51 BCDA 5 21 52ABCD 12 6 53 DABC 3 10 54 CDAB 10 15 55 BCDA 1 21 56ABCD 8 6 57 DABC 15 10 58 CDAB 6 15 59 BCDA 13 21 60ABCD 4 6 61 DABC 11 10 62 CDAB 2 15 63 BCDA 9 21 64 /* 然后进行如下操作 */A = A + AAB = B + BBC = C + CCD = D + DD end /* 结束对I的循环*/(5) 输出结果报文摘要的产生后的形式为:A,B,C,D。也就是低位字节A开始,高位字节D结束。现在完成了对MD5的描述,在附录中给出了C形式的程序。4 摘要MD5算法实现很容易,它提供了任意长度的信息的“指纹”(或称为报文摘要)。据推测要实现两个不同的报文产生相同的摘要需要264次的操作,要恢复给定摘要的报文则需要2128次操作。为寻找缺陷,MD5算法已经过非常细致的检查。最后的结论是还需要相关的更好的算法和更进一步的安全分析。5 MD4和MD5的区别以下是MD5和MD4的不同点:1 加上了第四轮循环。2 每一步增加了一个唯一的常数值。第二轮中的函数g从(XY v XZ v YZ)变成了(XZ v Y not(Z),以减少g函数的均衡性。6 参考文献1 Rivest, R., The MD4 Message Digest Algorithm, RFC 1320, MIT and RSA Data Security, Inc., April 1992.2 Rivest, R., The MD4 message digest algorithm, in A.J. Menezes and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO 90Proceedings, pages 303-311, Springer-Verlag, 1991. 3 CCITT Recommendation X.509 (1988), The Directory - Authentication Framework.7 附录A参考应用程序本附录包括以下文件:(摘自RSAREF: A Cryptographic Toolkit for Privacy-Enhanced Mail:) global.h 全局头文件md5.h - MD5头文件md5c.c - MD5源代码(要得到更多的RSAREF信息,请发e-mai到: .)附录中还包括:mddriver.cMD2, MD4 and MD5的测试驱动程序。驱动程序默认情况下编译MD5,但如果在C的编译命令行将MD5参数设成2或4,则也可以编译MD2和MD4此应用程序是方便使用的,可用在不同的平台上,在特殊的平台上优化它也并不困难,这留给读者作为练习。例如,在“little-endian”平台上,此平台32位字的最低地址字节最无意义的字节,并且没有队列限制,在MD5变换中的解码的命令调用可以被相应的类型替代。A1 global.h/* GLOBAL.H - RSAREF 类型和常数*/* 当且仅当编译器支持函数原型的声明时,PROTOTYPES必须被设置一次如果还没有定义C编译器的标记,下面的代码使PROTOTYPES置为0。*/#ifndef PROTOTYPES#define PROTOTYPES 0#endif/* POINTER 定义成一个普通的指针类型 */typedef unsigned char *POINTER;/* UINT2 定义成两字节的字 */typedef unsigned short int UINT2;/* UINT4定一成四字节的字 */typedef unsigned long int UINT4;/* PROTO_LIST的定义依赖于上面PROTOTYPES的定义,如果使用了PROTOTYPES,那么PROTO_LIST返回此列表,否则返回一个空列表。*/#if PROTOTYPES#define PROTO_LIST(list) list#else#define PROTO_LIST(list) ()#endifA.2 md5.h/*MD5.H - MD5C.C头文件*/*本软件允许被复制或运用,但必须在所有提及和参考的地方标注“RSA Data Security, Inc. MD5 Message-Digest Algorithm”,也允许产生或运用派生软件,但必须在所有提及和参考的地方标明“derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm” RSA数据安全公司(RSA Data Security, Inc.)从来没有出于任何特定目的陈述过关于此软件的可买性和实用性,它提供了“as is”,没有表达或暗示过任何理由。 此声明必须在任何此文件和软件的任何拷贝中保留。*/* MD5 context. */typedef struct UINT4 state4; /* state (ABCD) */ UINT4 count2; /* 位数量, 模 264 (低位在前) */ unsigned char buffer64; /* 输入缓冲器 */ MD5_CTX;void MD5Init PROTO_LIST (MD5_CTX *);void MD5Update PROTO_LIST (MD5_CTX *, unsigned char *, unsigned int);void MD5Final PROTO_LIST (unsigned char 16, MD5_CTX *);A.3 md5c.c/* MD5C.C RSA数据安全公司,MD5报文摘要算法*/*本软件允许被复制或运用,但必须在所有提及和参考的地方标注“RSA Data Security, Inc. MD5 Message-Digest Algorithm”也允许产生或运用派生软件,但必须在所有提及和参考的地方标明“derived from the RSA Data RSA数据安全公司(RSA Data Security, Inc.)从来没有出于任何特定目的陈述过关于此软件的可买性和实用性,它提供了“as is”,没有表达或暗示过任何理由。 此声明必须在任何此文件和软件的任何拷贝中保留。*/#include global.h#include md5.h/* Constants for MD5Transform routine. */#define S11 7#define S12 12#define S13 17#define S14 22#define S21 5#define S22 9#define S23 14#define S24 20#define S31 4#define S32 11#define S33 16#define S34 23#define S41 6#define S42 10#define S43 15#define S44 21static void MD5Transform PROTO_LIST (UINT4 4, unsigned char 64);static void Encode PROTO_LIST (unsigned char *, UINT4 *, unsigned int);static void Decode PROTO_LIST (UINT4 *, unsigned char *, unsigned int);static void MD5_memcpy PROTO_LIST (POINTER, POINTER, unsigned int);static void MD5_memset PROTO_LIST (POINTER, int, unsigned int);static unsigned char PADDING64 = 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;/* F, G, H 和 I 是基本MD5函数 */#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)/* ROTATE_LEFT 将x循环左移n位 */#define ROTATE_LEFT(x, n) (x) (32-(n)/* 循环从加法中分离出是为了防止重复计算*/#define FF(a, b, c, d, x, s, ac) (a) += F (b), (c), (d) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT (a), (s); (a) += (b); #define GG(a, b, c, d, x, s, ac) (a) += G (b), (c), (d) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT (a), (s); (a) += (b); #define HH(a, b, c, d, x, s, ac) (a) += H (b), (c), (d) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT (a), (s); (a) += (b); #define II(a, b, c, d, x, s, ac) (a) += I (b), (c), (d) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT (a), (s); (a) += (b); /* MD5 初始化. 开始一个MD5操作写一个新的context. */void MD5Init (context)MD5_CTX *context; /* context */ context-count0 = context-count1 = 0; context-state0 = 0x67452301; context-state1 = 0xefcdab89; context-state2 = 0x98badcfe; context-state3 = 0x10325476;/*MD5 分组更新操作. 继续一个MD5操作,处理另一个消息分组并更新context. */void MD5Update (context, input, inputLen)MD5_CTX *context; /* context */unsigned char *input; /* 输入分组*/unsigned int inputLen; /* 输入的分组的长度 */ unsigned int i, index, partLen; /* 计算字节数模64的值 */ index = (unsigned int)(context-count0 3) & 0x3F); /* Update number of bits */ if (context-count0 += (UINT4)inputLen 3) (UINT4)inputLen count1+; context-count1 += (UINT4)inputLen 29); partLen = 64 - index; /* 按能达到的最大次数转换*/ if (inputLen = partLen) MD5_memcpy (POINTER)&context-bufferindex, (POINTER)input, partLen); MD5Transform (context-state, context-buffer); for (i = partLen; i + 63 state, &inputi); index = 0; else i = 0; /* 缓冲器保留输入值 */ MD5_memcpy (POINTER)&context-bufferindex, (POINTER)&inputi, inputLen-i);/* MD5 最终结果. 以一个 MD5 报文摘要操作结束, 写下报文摘要值 */void MD5Final (digest, context)unsigned char digest16; /*报文摘要 */MD5_CTX *context; /* context */ unsigned char bits8; unsigned int index, padLen; /* 保存位数值 */ Encode (bits, context-count, 8); index = (unsigned int)(context-count0 3) & 0x3f); padLen = (index state, 16); MD5_memset (POINTER)context, 0, sizeof (*context);/* MD5基本转换. 转换状态基于分组*/static void MD5Transform (state, block)UINT4 state4;unsigned char block64; UINT4 a = state0, b = state1, c = state2, d = state3, x16; Decode (x, block, 64); /* Round 1 */ FF (a, b, c, d, x 0, S11, 0xd76aa478); /* 1 */ FF (d, a, b, c, x 1, S12, 0xe8c7b756); /* 2 */ FF (c, d, a, b, x 2, S13, 0x242070db); /* 3 */ FF (b, c, d, a, x 3, S14, 0xc1bdceee); /* 4 */ FF (a, b, c, d, x 4, S11, 0xf57c0faf); /* 5 */ FF (d, a, b, c, x 5, S12, 0x4787c62a); /* 6 */ FF (c, d, a, b, x 6, S13, 0xa8304613); /* 7 */ FF (b, c, d, a, x 7, S14, 0xfd469501); /* 8 */ FF (a, b, c, d, x 8, S11, 0x698098d8); /* 9 */ FF (d, a, b, c, x 9, S12, 0x8b44f7af); /* 10 */ FF (c, d, a, b, x10, S13, 0xffff5bb1); /* 11 */ FF (b, c, d, a, x11, S14, 0x895cd7be); /* 12 */ FF (a, b, c, d, x12, S11, 0x6b901122); /* 13 */ FF (d, a, b, c, x13, S12, 0xfd987193); /* 14 */ FF (c, d, a, b, x14, S13, 0xa679438e); /* 15 */ FF (b, c, d, a, x15, S14, 0x49b40821); /* 16 */ /* Round 2 */ GG (a, b, c, d, x 1, S21, 0xf61e2562); /* 17 */ GG (d, a, b, c, x 6, S22, 0xc040b340); /* 18 */ GG (c, d, a, b, x11, S23, 0x265e5a51); /* 19 */ GG (b, c, d, a, x 0, S24, 0xe9b6c7aa); /* 20 */ GG (a, b, c, d, x 5, S21, 0xd62f105d); /* 21 */ GG (d, a, b, c, x10, S22, 0x2441453); /* 22 */ GG (c, d, a, b, x15, S23, 0xd8a1e681); /* 23 */ GG (b, c, d, a, x 4, S24, 0xe7d3fbc8); /* 24 */ GG (a, b, c, d, x 9, S21, 0x21e1cde6); /* 25 */ GG (d, a, b, c, x14, S22, 0xc33707d6); /* 26 */ GG (c, d, a, b, x 3, S23, 0xf4d50d87); /* 27 */ GG (b, c, d, a, x 8, S24, 0x455a14ed); /* 28 */ GG (a, b, c, d, x13, S21, 0xa9e3e905); /* 29 */ GG (d, a, b, c, x 2, S22, 0xfcefa3f8); /* 30 */ GG (c, d, a, b, x 7, S23, 0x676f02d9); /* 31 */ GG (b, c, d, a, x12, S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH (a, b, c, d, x 5, S31, 0xfffa3942); /* 33 */ HH (d, a, b, c, x 8, S32, 0x8771f681); /* 34 */ HH (c, d, a, b, x11, S33, 0x6d9d6122); /* 35 */ HH (b, c, d, a, x14, S34, 0xfde5380c); /* 36 */ HH (a, b, c, d, x 1, S31, 0xa4beea44); /* 37 */ HH (d, a, b, c, x 4, S32, 0x4bdecfa9); /* 38 */ HH (c, d, a, b, x 7, S33, 0xf6bb4b60); /* 39 */ HH (b, c, d, a, x10, S34, 0xbebfbc70); /* 40 */ HH (a, b, c, d, x13, S31, 0x289b7ec6); /* 41 */ HH (d, a, b, c, x 0, S32, 0xeaa127fa); /* 42 */ HH (c, d, a, b, x 3, S33, 0xd4ef3085); /* 43 */ HH (b, c, d, a, x 6, S34, 0x4881d05); /* 44 */ HH (a, b, c, d, x 9, S31, 0xd9d4d039); /* 45 */ HH (d, a, b, c, x12, S32, 0xe6db99e5); /* 46 */ HH (c, d, a, b, x15, S33, 0x1fa27cf8); /* 47 */ HH (b, c, d, a, x 2, S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II (a, b, c, d, x 0, S41, 0xf4292244); /* 49 */ II (d, a, b, c, x 7, S42, 0x432aff97); /* 50 */ II (c, d, a, b, x14, S43, 0xab9423a7); /* 51 */ II (b, c, d, a, x 5, S44, 0xfc93a039); /* 52 */ II (a, b, c, d, x12, S41, 0x655b59c3); /* 53 */ II (d, a, b, c, x 3, S42, 0x8f0ccc92); /* 54 */ II (c, d, a, b, x10, S43, 0xffeff47d); /* 55 */ II (b, c, d, a, x 1, S44, 0x85845dd1); /* 56 */ II (a, b, c, d, x 8, S41, 0x6fa87e4f); /* 57 */ II (d, a, b, c, x15, S42, 0xfe2ce6e0); /* 58 */ II (c, d, a, b, x 6, S43, 0xa3014314); /* 59 */ II (b, c, d, a, x13, S44, 0x4e0811a1); /* 60 */ II (a, b, c, d, x 4, S41, 0xf7537e82); /* 61 */ II (d, a, b, c, x11, S42, 0xbd3af235); /* 62 */ II (c, d, a, b, x 2, S43, 0x2ad7d2bb); /* 63 */ II (b, c, d, a, x 9, S44, 0xeb86d391); /* 64 */ state0 += a; state1 += b; state2 += c; state3 += d; MD5_memset (POINTER)x, 0, sizeof (x);/* 将输入(UINT4)编码输出(unsigned char). 假设len是4的倍数 */static void Encode (output, input, len)unsigned char *output;UINT4 *input;unsigned int len; unsigned int i, j; for (i = 0, j = 0; j 8) & 0xff); outputj+2 = (unsigned char)(inputi 16) & 0xff); outputj+3 = (unsigned char)(inputi 24) & 0xff); /* 将输入(unsigned char)解码输出 (UINT4). 假设len是4的倍数 */static void Decode (output, input, len)UINT4 *output;unsigned char *input;unsigned int len; unsigned int i, j; for (i = 0, j = 0; j len; i+, j += 4) outputi = (UINT4)inputj) | (UINT4)inputj+1) 8) | (UINT4)inputj+2) 16) | (UINT4)inputj+3) 24);static void MD5_memcpy (output, input, len)POINTER output;POINTER input;unsigned int len; unsigned int i; for (i = 0; i len; i+) outputi = inputi;static void MD5_memset (output, value, len)POINTER output;int value;unsigned int len; unsigned int i; for (i = 0; i len; i+) (char *)output)i = (char)value;A.4 mddriver.c/* MDDRIVER.C - MD2, MD4 and MD5测试程序 */* RSA数据安全公司(RSA Data Security, Inc.)从来没有出于任何特定目的陈述过关于此软件的可买性和实用性,它提供了“as is”,没有表达或暗示过任何理由。此声明必须在任何此文件和软件的任何拷贝中保留。*/* 如果没有定义C编译标志的值,则MD5缺省状态下为MD5 */#ifndef MD#define MD MD5#endif#include #include #include #include global.h#if MD = 2#include md2.h#endif#if MD = 4#include md4.h#endif#if MD = 5#include md5.h#endif/* 测试分组长度和数量 */#define TEST_BLOCK_LEN 1000#define TEST_BLOCK_COUNT 1000static void MDString PROTO_LIST (char *);static void MDTimeTrial PROTO_LIST (void);static void MDTestSuite PROTO_LIST (void);static void MDFile PROTO_LIST (char *);static void MDFilter PROTO_LIST (void);static void MDPrint PROTO_LIST (unsigned char 16);#if MD = 2#define MD_CTX MD2_CTX#define MDInit MD2Init#define MDUpdate MD2Update#define MDFinal MD2Final#endif#if MD = 4#define MD_CTX MD4_CTX#define MDInit MD4Init#define MDUpdate MD4Update#define MDFinal MD4Final#endif#if MD = 5#define MD_CTX MD5_CTX#define MDInit MD5Init#define MDUpdate MD5Update#define MDFinal MD5Final#endif/* 主程序.变量: -sstring 摘要字符串 -t - 运行时间测试 -x - 运行测试脚本 filename 摘要文件 (none) - 摘要标准输入 */int main (argc, argv)int argc;char *argv; int i; if (argc 1) for (i = 1; i argc; i+) if (argvi0 = - & argvi1 = s) MDString (argvi + 2); else if (strcmp (argvi, -t) = 0) MDTimeTrial (); else if (strcmp (argvi, -x) = 0) MDTestSuite (); else MDFile (argvi); else MDFilter (); return (0);/* 计算字符串的摘要并打印其值 */static void MDString (string)char *string; MD_CTX context; unsigned char digest16; unsigned int len = strlen (string); MDInit (&context); MDUpdate (&context, string, len); MDFinal (digest, &context); printf (MD%d (%s) = , MD, string); MDPrint (digest); printf (n);/* 测试计算 TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte 分组摘要的时间 */static void MDTimeTrial () MD_CTX context; time_t endTime, startTime; unsigned char blockTEST_BLOCK_LEN, digest16; unsigned int i; printf (MD%d time trial. Digesting %d %d-byte blocks ., MD, TEST_BLOCK_LEN, TEST_BLOCK_COUNT); /* 初始化分组*/ for (i = 0; i TEST_BLOCK_LEN; i+) blocki = (unsigned char)(i & 0xff); /* 开始时钟 */ time (&startTime); /* 摘要分组 */ MDInit (&context); for (i = 0; i TEST_BLOCK_COUNT; i+) MDUpdate (&context, block, TEST_BLOCK_LEN); MDFinal (digest, &context); /* 停止时钟 */ time (&endTime); printf ( donen); printf (Digest = ); MDPrint (digest); printf (nTime = %ld secondsn, (long)(endTime-startTime); printf (Speed = %ld bytes/secondn, (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime);/* 计算一个参考组件串的摘要并打印结果*/static void MDTestSuite () printf (MD%d test suite:n, MD); MDString (); MDString (a); MDString (abc); MDString (message digest); MDString (abcdefghijklmnopqrstuvwxyz); MDString (ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789); MDString (12345678901234567890123456789012345678901234567890123456789012345678901234567890);/*计算一个文件的摘要并打印结果 */static void MDFile (filename)char *filename; FILE *file; MD_CTX context; int len; unsigned char buffer1024, digest16; if (file = fopen (filename, rb) = NULL) printf (%s cant be openedn, filename); else MDInit (&context); while (len = fread (buffer, 1, 1024, file) MDUpdate (&context, buffer, len); MDFinal (digest, &context); fclose (fi
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!