1 //  This file is part of par2cmdline (a PAR 2.0 compatible file verification and
2 //  repair tool). See http://parchive.sourceforge.net for details of PAR 2.0.
3 //
4 //  Copyright (c) 2003 Peter Brian Clements
5 //
6 //  par2cmdline is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 2 of the License, or
9 //  (at your option) any later version.
10 //
11 //  par2cmdline is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19 
20 #ifndef __MD5_H__
21 #define __MD5_H__
22 
23 #ifdef WIN32
24 #pragma pack(push, 1)
25 #define PACKED
26 #else
27 #define PACKED __attribute__ ((packed))
28 #endif
29 
30 // This file defines the MD5Hash and MD5Context objects which are used
31 // to compute and manipulate the MD5 Hash values for a block of data.
32 
33 //  Usage:
34 //
35 //  MD5Context context;
36 //  context.Update(buffer, length);
37 //
38 //  MD5Hash hash;
39 //  context.Final(hash);
40 
41 
42 
43 // MD5 Hash value
44 
45 struct MD5Hash;
46 ostream& operator<<(ostream &s, const MD5Hash &hash);
47 
48 struct MD5Hash
49 {
50   // Comparison operators
51   bool operator==(const MD5Hash &other) const;
52   bool operator!=(const MD5Hash &other) const;
53 
54   bool operator<(const MD5Hash &other) const;
55   bool operator>=(const MD5Hash &other) const;
56   bool operator>(const MD5Hash &other) const;
57   bool operator<=(const MD5Hash &other) const;
58 
59   // Convert value to hex
60   friend ostream& operator<<(ostream &s, const MD5Hash &hash);
61   string print(void) const;
62 
63   u8 hash[16]; // 16 byte MD5 Hash value
64 } PACKED;
65 
66 // Intermediate computation state
67 
68 class MD5State
69 {
70 public:
71   MD5State(void);
72   void Reset(void);
73 
74 public:
75   void UpdateState(const u32 (&block)[16]);
76 
77 protected:
78   u32 state[4]; // 16 byte MD5 computation state
79 };
80 
81 // MD5 computation context with 64 byte buffer
82 
83 class MD5Context : public MD5State
84 {
85 public:
86   MD5Context(void);
~MD5Context(void)87   ~MD5Context(void) {};
88   void Reset(void);
89 
90   // Process data from a buffer
91   void Update(const void *buffer, size_t length);
92 
93   // Process 0 bytes
94   void Update(size_t length);
95 
96   // Compute the final hash value
97   void Final(MD5Hash &output);
98 
99   // Get the Hash value and the total number of bytes processed.
100   MD5Hash Hash(void) const;
Bytes(void)101   u64 Bytes(void) const {return bytes;}
102 
103   friend ostream& operator<<(ostream &s, const MD5Context &context);
104   string print(void) const;
105 
106 protected:
107   enum {buffersize = 64};
108   unsigned char block[buffersize];
109   size_t used;
110 
111   u64 bytes;
112 };
113 
114 // Compare hash values
115 
116 inline bool MD5Hash::operator==(const MD5Hash &other) const
117 {
118   return (0==memcmp(&hash, &other.hash, sizeof(hash)));
119 }
120 inline bool MD5Hash::operator!=(const MD5Hash &other) const
121 {
122   return !operator==(other);
123 }
124 
125 inline bool MD5Hash::operator<(const MD5Hash &other) const
126 {
127   size_t index = 15;
128   while (index > 0 && hash[index] == other.hash[index])
129   {
130     index--;
131   }
132 
133   return hash[index] < other.hash[index];
134 }
135 inline bool MD5Hash::operator>=(const MD5Hash &other) const
136 {
137   return !operator<(other);
138 }
139 inline bool MD5Hash::operator>(const MD5Hash &other) const
140 {
141   return other.operator<(*this);
142 }
143 inline bool MD5Hash::operator<=(const MD5Hash &other) const
144 {
145   return !other.operator<(*this);
146 }
147 
148 #ifdef WIN32
149 #pragma pack(pop)
150 #endif
151 #undef PACKED
152 
153 #endif // __MD5_H__
154