📄 zmd5.h
字号:
/*-======================- Copyright (c) 2006 -======================-
程序作者:
张鲁夺(zhangluduo) : 为所有爱我的人和我爱的人努力!
联系方式:
oopfans@msn.com
修改时间:
2007-02-19
功能描述:
将原信息加密成MD5摘要这个类的头文件下面附上了ronald l. rivest在
1992年8月向ieft提交的rfc1321.txt,这是一份最权威的文档.
使用说明:
这个类是一个虚基类,要使用这个类必须继承自这个类,并实现这个类里的
virtual void OnProcessing(int PrcessNum)=0;纯虚函数,这个纯虚函数
用于在对一个较大文件进行MD5计算时,将处理进度返回给用户
版权声明:
许可任何单位,个人随意使用,拷贝,修改,散布及出售这份代码,但是必须保
留此版权信息,以慰藉作者辛勤的劳动,及表明此代码的来源,如若此份代码
有任何BUG,请通知作者,以便弥补作者由于水平所限而导致的一些错误和不
足,谢谢!
-======================- Copyright (c) 2006 -======================-*/
#ifndef _ZMD5
#define _ZMD5
#define for if(0); else for
//读取文件的缓冲区,这个值必须是64的整数倍
#define FILE_BUFFER_READ 1048576
#include <io.h>
#include <string>
using namespace std;
class ZMD5
{
public:
ZMD5();
virtual ~ZMD5();
private:
//四个寄存器具变量
unsigned int A,B,C,D;
//常量
int S11, S21, S31, S41;
int S12, S22, S32, S42;
int S13, S23, S33, S43;
int S14, S24, S34, S44;
//对原始信息需要追加的字节数
int m_AppendByte;
//原始信息长度,用一个64位整数记录
unsigned char m_MsgLen[8];
private:
//位移函数
unsigned int ROTATE_LEFT(unsigned int x,unsigned int n);
unsigned int F(unsigned int x,unsigned int y,unsigned int z);
unsigned int G(unsigned int x,unsigned int y,unsigned int z);
unsigned int H(unsigned int x,unsigned int y,unsigned int z);
unsigned int I(unsigned int x,unsigned int y,unsigned int z);
//四轮变换函数
void FF(unsigned int& a,unsigned int b,unsigned int c,unsigned int d,unsigned int x,int s,unsigned int ac);
void GG(unsigned int& a,unsigned int b,unsigned int c,unsigned int d,unsigned int x,int s,unsigned int ac);
void HH(unsigned int& a,unsigned int b,unsigned int c,unsigned int d,unsigned int x,int s,unsigned int ac);
void II(unsigned int& a,unsigned int b,unsigned int c,unsigned int d,unsigned int x,int s,unsigned int ac);
//初始化MD5所需参数
void Init();
//计算追加字节数及记录原始信息长度
void Append(unsigned int MsgLen);
//将原始信息以64字节进行分组,进行错位打乱
void Transform(unsigned char Block[64]);
//将寄存器A,B,C,D中最后保存的值转换为十六进制并返回给用户
string ToHex(bool UpperCase);
public:
//计算字符串的MD5
string GetMD5OfString(string InputMessage,bool UpperCase);
private:
//文件指针,声明在此处是因为有必要在函数外部关闭文件指针
FILE* m_pFile;
//文件的打开状态,GetMD5OfFile函数根据此值决定是否继续计算
bool m_FileOpen;
public:
//计算文件的MD5
string GetMD5OfFile(const string FileName,bool UpperCase);
//允许用户从函数外部提前结束对GetMD5OfFile的调用
void GetMD5OfFile_Terminate();
private:
//纯虚函数,在计算文件MD5的过程中,通过PrcessNum将处理进度传递到子类中
virtual void OnProcessing(int PrcessNum)=0;
};
#endif
// rfc1321.txt full content
//
// Network Working Group R. Rivest
// Request for Comments: 1321 MIT Laboratory for Computer Science
// and RSA Data Security, Inc.
// April 1992
//
//
// The MD5 Message-Digest Algorithm
//
// Status of this Memo
//
// This memo provides information for the Internet community. It does
// not specify an Internet standard. Distribution of this memo is
// unlimited.
//
// Acknowlegements
//
// We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
// David Chaum, and Noam Nisan for numerous helpful comments and
// suggestions.
//
// Table of Contents
//
// 1. Executive Summary 1
// 2. Terminology and Notation 2
// 3. MD5 Algorithm Description 3
// 4. Summary 6
// 5. Differences Between MD4 and MD5 6
// References 7
// APPENDIX A - Reference Implementation 7
// Security Considerations 21
// Author's Address 21
//
// 1. Executive Summary
//
// This document describes the MD5 message-digest algorithm. The
// algorithm takes as input a message of arbitrary length and produces
// as output a 128-bit "fingerprint" or "message digest" of the input.
// It is conjectured that it is computationally infeasible to produce
// two messages having the same message digest, or to produce any
// message having a given prespecified target message digest. The MD5
// algorithm is intended for digital signature applications, where a
// large file must be "compressed" in a secure manner before being
// encrypted with a private (secret) key under a public-key cryptosystem
// such as RSA.
//
// Rivest [Page 1]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// The MD5 algorithm is designed to be quite fast on 32-bit machines. In
// addition, the MD5 algorithm does not require any large substitution
// tables; the algorithm can be coded quite compactly.
//
// The MD5 algorithm is an extension of the MD4 message-digest algorithm
// 1,2]. MD5 is slightly slower than MD4, but is more "conservative" in
// design. MD5 was designed because it was felt that MD4 was perhaps
// being adopted for use more quickly than justified by the existing
// critical review; because MD4 was designed to be exceptionally fast,
// it is "at the edge" in terms of risking successful cryptanalytic
// attack. MD5 backs off a bit, giving up a little in speed for a much
// greater likelihood of ultimate security. It incorporates some
// suggestions made by various reviewers, and contains additional
// optimizations. The MD5 algorithm is being placed in the public domain
// for review and possible adoption as a standard.
//
// For OSI-based applications, MD5's object identifier is
//
// md5 OBJECT IDENTIFIER ::=
// iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}
//
// In the X.509 type AlgorithmIdentifier [3], the parameters for MD5
// should have type NULL.
//
// 2. Terminology and Notation
//
// In this document a "word" is a 32-bit quantity and a "byte" is an
// eight-bit quantity. A sequence of bits can be interpreted in a
// natural manner as a sequence of bytes, where each consecutive group
// of eight bits is interpreted as a byte with the high-order (most
// significant) bit of each byte listed first. Similarly, a sequence of
// bytes can be interpreted as a sequence of 32-bit words, where each
// consecutive group of four bytes is interpreted as a word with the
// low-order (least significant) byte given first.
//
// Let x_i denote "x sub i". If the subscript is an expression, we
// surround it in braces, as in x_{i+1}. Similarly, we use ^ for
// superscripts (exponentiation), so that x^i denotes x to the i-th
// power.
//
// Let the symbol "+" denote addition of words (i.e., modulo-2^32
// addition). Let X <<< s denote the 32-bit value obtained by circularly
// shifting (rotating) X left by s bit positions. Let not(X) denote the
// bit-wise complement of X, and let X v Y denote the bit-wise OR of X
// and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY
// denote the bit-wise AND of X and Y.
//
// Rivest [Page 2]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// 3. MD5 Algorithm Description
//
// We begin by supposing that we have a b-bit message as input, and that
// we wish to find its message digest. Here b is an arbitrary
// nonnegative integer; b may be zero, it need not be a multiple of
// eight, and it may be arbitrarily large. We imagine the bits of the
// message written down as follows:
//
// m_0 m_1 ... m_{b-1}
//
// The following five steps are performed to compute the message digest
// of the message.
//
// 3.1 Step 1. Append Padding Bits
//
// The message is "padded" (extended) so that its length (in bits) is
// congruent to 448, modulo 512. That is, the message is extended so
// that it is just 64 bits shy of being a multiple of 512 bits long.
// Padding is always performed, even if the length of the message is
// already congruent to 448, modulo 512.
//
// Padding is performed as follows: a single "1" bit is appended to the
// message, and then "0" bits are appended so that the length in bits of
// the padded message becomes congruent to 448, modulo 512. In all, at
// least one bit and at most 512 bits are appended.
//
// 3.2 Step 2. Append Length
//
// A 64-bit representation of b (the length of the message before the
// padding bits were added) is appended to the result of the previous
// step. In the unlikely event that b is greater than 2^64, then only
// the low-order 64 bits of b are used. (These bits are appended as two
// 32-bit words and appended low-order word first in accordance with the
// previous conventions.)
//
// At this point the resulting message (after padding with bits and with
// b) has a length that is an exact multiple of 512 bits. Equivalently,
// this message has a length that is an exact multiple of 16 (32-bit)
// words. Let M[0 ... N-1] denote the words of the resulting message,
// where N is a multiple of 16.
//
// 3.3 Step 3. Initialize MD Buffer
//
// A four-word buffer (A,B,C,D) is used to compute the message digest.
// Here each of A, B, C, D is a 32-bit register. These registers are
// initialized to the following values in hexadecimal, low-order bytes
// first):
//
// Rivest [Page 3]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// word A: 01 23 45 67
// word B: 89 ab cd ef
// word C: fe dc ba 98
// word D: 76 54 32 10
//
// 3.4 Step 4. Process Message in 16-Word Blocks
//
// We first define four auxiliary functions that each take as input
// three 32-bit words and produce as output one 32-bit word.
//
// 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))
//
// In each bit position F acts as a conditional: if X then Y else Z.
// The function F could have been defined using + instead of v since XY
// and not(X)Z will never have 1's in the same bit position.) It is
// interesting to note that if the bits of X, Y, and Z are independent
// and unbiased, the each bit of F(X,Y,Z) will be independent and
// unbiased.
//
// The functions G, H, and I are similar to the function F, in that they
// act in "bitwise parallel" to produce their output from the bits of X,
// Y, and Z, in such a manner that if the corresponding bits of X, Y,
// and Z are independent and unbiased, then each bit of G(X,Y,Z),
// H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
// the function H is the bit-wise "xor" or "parity" function of its
// inputs.
//
// This step uses a 64-element table T[1 ... 64] constructed from the
// sine function. Let T[i] denote the i-th element of the table, which
// is equal to the integer part of 4294967296 times abs(sin(i)), where i
// is in radians. The elements of the table are given in the appendix.
//
// Do the following:
//
// /* Process each 16-word block. */
// For i = 0 to N/16-1 do
//
// /* Copy block i into X. */
// For j = 0 to 15 do
// Set X[j] to M[i*16+j].
// end /* of loop on j */
//
// /* Save A as AA, B as BB, C as CC, and D as DD. */
// AA = A
// BB = B
//
// Rivest [Page 4]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// CC = C
// DD = D
//
// /* Round 1. */
// /* Let [abcd k s i] denote the operation
// a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
// /* Do the following 16 operations. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -