1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//
// md5.h
//
//
// A pretty fast implementation of MD5
//
#ifndef __MD5_H__
#define __MD5_H__
/////////////////////////////////////////////////////////////////////////////////////
//
// Declaration of the central transform function
//
void __stdcall MD5Transform(ULONG state[4], const ULONG* data);
/////////////////////////////////////////////////////////////////////////////////////
#include <pshpack1.h>
// This structure is used to return the final resulting hash.
//
struct MD5HASHDATA
{
union
{
BYTE rgb[16];
struct
{
ULONGLONG ullLow;
ULONGLONG ullHigh;
} u;
struct
{
ULONG u0;
ULONG u1;
ULONG u2;
ULONG u3;
} v;
};
};
inline BOOL operator==(const MD5HASHDATA& me, const MD5HASHDATA& him)
{
return memcmp(&me, &him, sizeof(MD5HASHDATA)) == 0;
}
inline BOOL operator!=(const MD5HASHDATA& me, const MD5HASHDATA& him)
{
return memcmp(&me, &him, sizeof(MD5HASHDATA)) != 0;
}
// The engine that carries out the hash
//
class MD5
{
// These four values must be contiguous, and in this order
union
{
ULONG m_state[4];
struct
{
ULONG m_a; // state
ULONG m_b; // ... variables
ULONG m_c; // ... as found in
ULONG m_d; // ... RFC1321
} u;
};
BYTE m_data[64]; // where to accumulate the data as we are passed it
ULONGLONG m_cbitHashed; // amount of data that we've hashed
ULONG m_cbData; // number of bytes presently in data
BYTE m_padding[64]; // padding data, used if length data not = 0 mod 64
public:
/////////////////////////////////////////////////////////////////////////////////////
void Hash(const BYTE* pbData, ULONG cbData, MD5HASHDATA* phash, BOOL fConstructed = FALSE)
{
Init(fConstructed);
HashMore(pbData, cbData);
GetHashValue(phash);
}
/////////////////////////////////////////////////////////////////////////////////////
void Hash(const BYTE* pbData, ULONGLONG cbData, MD5HASHDATA* phash, BOOL fConstructed = FALSE)
{
Init(fConstructed);
ULARGE_INTEGER ul;
ul.QuadPart = cbData;
while (ul.u.HighPart)
{
ULONG cbHash = 0xFFFFFFFF; // Hash as much as we can at once
HashMore(pbData, cbHash);
pbData += cbHash;
ul.QuadPart -= cbHash;
}
HashMore(pbData, ul.u.LowPart); // Hash whatever is left
GetHashValue(phash);
}
/////////////////////////////////////////////////////////////////////////////////////
void Init(BOOL fConstructed = FALSE);
/////////////////////////////////////////////////////////////////////////////////////
void HashMore(const void* pvInput, ULONG cbInput);
/////////////////////////////////////////////////////////////////////////////////////
void GetHashValue(MD5HASHDATA* phash);
/////////////////////////////////////////////////////////////////////////////////////
};
#include <poppack.h>
#endif
|