opennurbs_md5.h
1 /*
2 //
3 // Copyright (c) 1993-2015 Robert McNeel & Associates. All rights reserved.
4 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
5 // McNeel & Associates.
6 //
7 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
8 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
9 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
10 //
11 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
12 //
13 ////////////////////////////////////////////////////////////////
14 */
15 
16 #if !defined(OPENNURBS_MD5_INC_)
17 #define OPENNURBS_MD5_INC_
18 
19 /*
20 The ON_MD5 class is based on code that is modified from C code with the following copyright.
21 
22 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
23 
24  License to copy and use this software is granted provided that it
25  is identified as the "RSA Data Security, Inc. MD5 Message-Digest
26  Algorithm" in all material mentioning or referencing this software
27  or this function.
28 
29  License is also granted to make and use derivative works provided
30  that such works are identified as "derived from the RSA Data
31  Security, Inc. MD5 Message-Digest Algorithm" in all material
32  mentioning or referencing the derived work.
33 
34  RSA Data Security, Inc. makes no representations concerning either
35  the merchantability of this software or the suitability of this
36  software for any particular purpose. It is provided "as is"
37  without express or implied warranty of any kind.
38 
39  These notices must be retained in any copies of any part of this
40  documentation and/or software.
41 */
42 class ON_CLASS ON_MD5_Hash
43 {
44 public:
45  static const ON_MD5_Hash ZeroDigest; // all digest bytes are zero
46  static const ON_MD5_Hash EmptyContentHash; // MD5 hash of zero bytes
47 
48  // Default constructor is the zero digest hash
49  ON_MD5_Hash();
50 
51  ~ON_MD5_Hash() = default;
52  ON_MD5_Hash(const ON_MD5_Hash&) = default;
53  ON_MD5_Hash& operator=(const ON_MD5_Hash&) = default;
54 
55  /*
56  Parameters:
57  buffer - [in]
58  sizeof_buffer - [in]
59  number of bytes in buffer
60  Returns:
61  MD5 hash of the buffer.
62  */
63  static ON_MD5_Hash BufferHash(
64  const void* buffer,
65  size_t sizeof_buffer
66  );
67 
68  /*
69  Parameters:
70  filename - [in]
71  Name of file
72  sizeof_file - [out]
73  number of bytes in file
74  Returns:
75  MD5 hash of the buffer.
76  */
77  static ON_MD5_Hash FileHash(
78  const wchar_t* filename,
79  ON__UINT64& sizeof_file
80  );
81 
82  static ON_MD5_Hash FileHash(
83  const char* filename,
84  ON__UINT64& sizeof_file
85  );
86 
87  /*
88  Parameters:
89  file - [in]
90  File stream from ON_FileStream::Open(...,L"rb");
91  sizeof_file - [out]
92  number of bytes in file
93  Returns:
94  MD5 hash of the file stream from the current
95  offset to the end of the file.
96  */
97  static ON_MD5_Hash FileHash(
98  FILE* file,
99  ON__UINT64& sizeof_file
100  );
101 
102  /*
103  Parameters:
104  str - [in]
105  string
106  byte_count - [out]
107  number of bytes in UTF-8 encoding of the string.
108  Returns:
109  MD5 hash of the UTF-8 encoding of the string. (Platforms and endian independent.)
110  */
111  static ON_MD5_Hash StringHash(
112  const ON_wString& str,
113  ON__UINT64& byte_count
114  );
115 
116  static ON_MD5_Hash StringHash(
117  const wchar_t* str,
118  size_t str_length,
119  ON__UINT64& byte_count
120  );
121 
122  /*
123  Parameters:
124  str - [in]
125  byte_count - [out]
126  number of bytes in the string.
127  Returns:
128  MD5 hash of the UTF-8 encoding of the string. (Platforms and endian independent.)
129  */
130  static ON_MD5_Hash StringHash(
131  const ON_String& str,
132  ON__UINT64& byte_count
133  );
134 
135  static ON_MD5_Hash StringHash(
136  const char* str,
137  size_t str_length,
138  ON__UINT64& byte_count
139  );
140 
141  static int Compare(
142  const ON_MD5_Hash& a,
143  const ON_MD5_Hash& b
144  );
145 
146  /*
147  Parameters:
148  bUpperCaseHexadecimalDigits - [in]
149  false - use 0-9, a-f
150  true - use 0-9, A-F
151  Returns:
152  The MD5 hash value as a 32 hexadecimal digits.
153  The first digit in the string is the hexadecimal value of m_digest[0].
154  */
155  const ON_String ToUTF8String(
156  bool bUpperCaseHexadecimalDigits
157  ) const;
158 
159  /*
160  Parameters:
161  bUpperCaseHexadecimalDigits - [in]
162  false - use 0-9, a-f
163  true - use 0-9, A-F
164  Returns:
165  The MD5 hash value as a 32 hexadecimal digits.
166  The first digit in the string is the hexadecimal value of m_digest[0].
167  */
168  const ON_wString ToString(
169  bool bUpperCaseHexadecimalDigits
170  ) const;
171 
172  bool Read(
173  class ON_BinaryArchive& archive
174  );
175 
176  bool Write(
177  class ON_BinaryArchive& archive
178  ) const;
179 
180  void Dump(
181  class ON_TextLog& text_log
182  ) const;
183 
184  ON__UINT8 m_digest[16];
185 };
186 
187 ON_DECL
188 bool operator==(const ON_MD5_Hash& a, const ON_MD5_Hash& b);
189 
190 ON_DECL
191 bool operator!=(const ON_MD5_Hash& a, const ON_MD5_Hash& b);
192 
193 /*
194 Description:
195  ON_MD5 is a small class for calculating the MD5 hash of a sequence of bytes.
196  It may be use incrementally (the bytes do not have to be in a contiguous
197  array in memory at one time).
198 
199 Remarks:
200  The ON_MD5 class cannot be used for cryptographic or security applications.
201  The MD5 hash algorithm is not suitable for cryptographic or security applications.
202  The ON_MD5 class does not "wipe" intermediate results.
203 
204  The probability of two different randomly selected seqences of N bytes to have the
205  same value MD5 hash depends on N, but it is roughly 2^-64 ~ 10^-19.
206 
207  MD5 hash values are 16 bytes. SHA-1 hash values are 20 bytes. If you need a hash
208  and have room for 20 bytes, then ON_SHA1 is preferred over ON_MD5.
209 
210 Legal:
211  Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
212 
213  License to copy and use this software is granted provided that it
214  is identified as the "RSA Data Security, Inc. MD5 Message-Digest
215  Algorithm" in all material mentioning or referencing this software
216  or this function.
217 
218  License is also granted to make and use derivative works provided
219  that such works are identified as "derived from the RSA Data
220  Security, Inc. MD5 Message-Digest Algorithm" in all material
221  mentioning or referencing the derived work.
222 
223  RSA Data Security, Inc. makes no representations concerning either
224  the merchantability of this software or the suitability of this
225  software for any particular purpose. It is provided "as is"
226  without express or implied warranty of any kind.
227 
228  These notices must be retained in any copies of any part of this
229  documentation and/or software.
230 */
231 class ON_CLASS ON_MD5
232 {
233 public:
234 
235  ON_MD5() = default;
236  ~ON_MD5() = default;
237  ON_MD5(const ON_MD5&) = default;
238  ON_MD5& operator=(const ON_MD5&) = default;
239 
240  /*
241  Description:
242  Make one or more calls to AccumulateBytes() as the sequenence of bytes is available.
243  Parameters:
244  buffer - [in]
245  sizeof_buffer - [in]
246  number of bytes in buffer
247  */
248 #if defined(ON_COMPILER_MSC) && defined(NDEBUG)
249  // Reduces release build link time optimization by several hours for
250  // large programs that make lots of calls to ON_MD5.Accumulate*() functions.
251  __declspec(noinline)
252 #endif
253  void AccumulateBytes(
254  const void* buffer,
255  ON__UINT64 sizeof_buffer
256  );
257 
258  /*
259  Returns:
260  Total number of bytes passed to Update().
261  */
262  ON__UINT64 ByteCount() const;
263 
264  /*
265  Returns:
266  MD5 hash value of the sequenence of ByteCount() bytes that have been
267  passed to this ON_MD5 classe's Update() function since construction
268  or the last call to Reset().
269  Remarks:
270  You may use Hash() to compute intermediate MD5 hash values.
271 
272  Put another way, you may call Update() zero or more times passing in N1 bytes,
273  call Digest() to get the MD5 hash of those N1 bytes, make zero or more additional
274  calls to Update() passing in N2 additional bytes, call digest to get the MD5 hash
275  of the seqence of (N1 + N2) bytes, and so on.
276  */
277  ON_MD5_Hash Hash() const;
278 
279  /*
280  Description:
281  Reset this ON_MD5 class so it can be reused.
282  */
283  void Reset();
284 
285  /*
286  Description:
287  This is a static function that uses ON_MD5 to compute MD5 hash values
288  of sequences of bytes with known MD5 hash values and compares the
289  results from ON_SHA1 with the known MD5 hash values.
290 
291  This function can be used to validate the ON_MD5 class compiled correctly.
292 
293  Returns:
294  true
295  All validation tests passed.
296  false
297  At least one validation test failed.
298  */
299  static bool Validate();
300 
301 private:
302  void Internal_Accumulate(const ON__UINT8* input, ON__UINT32 length);
303  void set_final_hash();
304 
305  ON__UINT64 m_byte_count = 0; // number of bytes that have passed through calls to Update().
306  // if 1 == m_status_bits & 1, then Update has been called at least once (perhaps with 0 bytes).
307  // if 2 == m_status_bits & 2, then m_md5_hash is current.
308  mutable ON__UINT32 m_status_bits = 0;
309  ON__UINT32 m_reserved = 0;
310 
311  // current "remainder"
312  ON__UINT8 m_buffer[64]; // bytes that didn't fit in last 64 byte chunk
313  ON__UINT32 m_bit_count[2]; // number of bits (lo, hi)
314  ON__UINT32 m_state[4]; // current state
315 
316  // chached MD5 hash - valid if 2 = (2 & m_status_bits)
317  mutable ON_MD5_Hash m_md5_hash;
318 };
319 
320 #endif
ON_MD5 is a small class for calculating the MD5 hash of a sequence of bytes. It may be use incrementa...
Definition: opennurbs_md5.h:218
Definition: opennurbs_string.h:2020
static const ON_MD5_Hash ZeroDigest
Definition: opennurbs_md5.h:45
static const ON_MD5_Hash EmptyContentHash
Definition: opennurbs_md5.h:46
Definition: opennurbs_string.h:852
Definition: opennurbs_md5.h:42
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783