opennurbs_sha1.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_SHA1_INC_)
17 #define OPENNURBS_SHA1_INC_
18 
19 class ON_CLASS ON_SHA1_Hash
20 {
21 public:
22  static const ON_SHA1_Hash ZeroDigest; // all digest bytes are zero
23  static const ON_SHA1_Hash EmptyContentHash; // SHA-1 hash of zero bytes
24 
25  // The default constructor creates a zero digest sha1 hash
26  ON_SHA1_Hash();
27 
28  ~ON_SHA1_Hash() = default;
29  ON_SHA1_Hash(const ON_SHA1_Hash&) = default;
30  ON_SHA1_Hash& operator=(const ON_SHA1_Hash&) = default;
31 
32  static int Compare(
33  const ON_SHA1_Hash& a,
34  const ON_SHA1_Hash& b
35  );
36 
37  /*
38  Parameters:
39  buffer - [in]
40  sizeof_buffer - [in]
41  number of bytes in buffer
42  Returns:
43  SHA1-1 hash of the buffer.
44  */
45  static ON_SHA1_Hash BufferContentHash(
46  const void* buffer,
47  size_t sizeof_buffer
48  );
49 
50  /*
51  Parameters:
52  file_name - [in]
53  Name of file
54  sizeof_file - [out]
55  number of bytes in file
56  Returns:
57  SHA1-1 hash of the buffer.
58  */
59  static ON_SHA1_Hash FileContentHash(
60  const wchar_t* file_name,
61  ON__UINT64& sizeof_file
62  );
63 
64  static ON_SHA1_Hash FileContentHash(
65  const char* file_name,
66  ON__UINT64& sizeof_file
67  );
68 
69  /*
70  Description:
71  Return a hash of the file system path that is independent
72  of the size of wchar_t, constant across platforms, and
73  constant across varations in the way the path is formatted.
74 
75  Parameters:
76  path - [in]
77  File system path to a directory or file.
78 
79  Returns:
80  SHA1-1 hash of the buffer.
81 
82  Example:
83  These file system paths have identical values of FileSystemPathHash().
84  /x/y/z/name.ext
85  \x\y\z\name.ext
86  /x//y//z/name.ext
87  /x/y/a/b/c/../../../z/name.ext
88  /X/Y/Z/NAME.EXT (When ON_ComparePathIgnoreCase() is true)
89 
90  Remarks:
91  This function uses the value of ON_FileSystemPath::PlatformPathIgnoreCase()
92  to determine if case should be ignored. Use the version with a bIgnoreCase
93  parameter if you want to explicitly control this decision.
94  */
95  static ON_SHA1_Hash FileSystemPathHash(
96  const wchar_t* path
97  );
98 
99  static ON_SHA1_Hash FileSystemPathHash(
100  const char* path
101  );
102 
103  static ON_SHA1_Hash FileSystemPathHash(
104  const wchar_t* path,
105  bool bIgnoreCase
106  );
107 
108  static ON_SHA1_Hash FileSystemPathHash(
109  const char* path,
110  bool bIgnoreCase
111  );
112 
113  /*
114  Parameters:
115  file - [in]
116  File stream from ON_FileStream::Open(...,L"rb");
117  sizeof_file - [out]
118  number of bytes in file
119  Returns:
120  SHA1-1 hash of the file stream from the current
121  offset to the end of the file.
122  */
123  static ON_SHA1_Hash FileContentHash(
124  FILE* file,
125  ON__UINT64& sizeof_file
126  );
127 
128  /*
129  Parameters:
130  str - [in]
131  string
132  byte_count - [out]
133  number of bytes in UTF-8 encoding of the string.
134  Returns:
135  SHA1-1 hash of the UTF-8 encoding of the string. (Platforms and endian independent.)
136  */
137  static ON_SHA1_Hash StringHash(
138  const ON_wString& str,
139  ON__UINT64& byte_count
140  );
141 
142  static ON_SHA1_Hash StringHash(
143  const wchar_t* str,
144  size_t str_length,
145  ON__UINT64& byte_count
146  );
147 
148  static ON_SHA1_Hash StringHash(
149  const wchar_t* null_terminated_string
150  );
151 
152  /*
153  Parameters:
154  str - [in]
155  byte_count - [out]
156  number of bytes in the string.
157  Returns:
158  SHA1-1 hash of the UTF-8 encoding of the string. (Platforms and endian independent.)
159  */
160  static ON_SHA1_Hash StringHash(
161  const ON_String& str,
162  ON__UINT64& byte_count
163  );
164 
165  static ON_SHA1_Hash StringHash(
166  const char* str,
167  size_t str_length,
168  ON__UINT64& byte_count
169  );
170 
171 
172  static ON_SHA1_Hash StringHash(
173  const char* null_terminated_string
174  );
175 
176  /*
177  Parameters:
178  bUpperCaseHexadecimalDigits - [in]
179  false - use 0-9, a-f
180  true - use 0-9, A-F
181  Returns:
182  The SHA-1 hash value as a 40 hexadecimal digits.
183  The first digit in the string is the hexadecimal value of m_digest[0].
184  */
185  const ON_String ToUTF8String(
186  bool bUpperCaseHexadecimalDigits
187  ) const;
188 
189  /*
190  Parameters:
191  bUpperCaseHexadecimalDigits - [in]
192  false - use 0-9, a-f
193  true - use 0-9, A-F
194  Returns:
195  The SHA-1 hash value as a 40 hexadecimal digits.
196  The first digit in the string is the hexadecimal value of m_digest[0].
197  */
198  const ON_wString ToString(
199  bool bUpperCaseHexadecimalDigits
200  ) const;
201 
202  bool Read(
203  class ON_BinaryArchive& archive
204  );
205 
206  bool Write(
207  class ON_BinaryArchive& archive
208  ) const;
209 
210  void Dump(
211  class ON_TextLog& text_log
212  ) const;
213 
214  /*
215  Returns:
216  True if this and ON_SHA1_Hash::ZeroDigest have identical digest values.
217  */
218  bool IsZeroDigest() const;
219 
220  /*
221  Returns:
222  True if this and ON_SHA1_Hash::EmptyContentHash have identical digest values.
223  */
224  bool IsEmptyContentHash() const;
225 
226  bool IsZeroDigentOrEmptyContentHash() const;
227 
228  ON__UINT8 m_digest[20];
229 };
230 
231 
232 
233 ON_DECL
234 bool operator==(const ON_SHA1_Hash& a, const ON_SHA1_Hash& b);
235 
236 ON_DECL
237 bool operator!=(const ON_SHA1_Hash& a, const ON_SHA1_Hash& b);
238 
239 /*
240 Description:
241  ON_SHA1 is a small class for calculating the SHA-1 hash of a sequence of bytes.
242  It may be use incrementally (the bytes do not have to be in a contiguous
243  array in memory at one time).
244 
245 Remarks:
246  The ON_SHA1 class cannot be used for cryptographic or security applications.
247  The SHA-1 hash algorithm is not suitable for cryptographic or security applications.
248  The ON_SHA1 class does not "wipe" intermediate results.
249 
250  If you have two different seqences of N bytes storing information (lower entropy
251  than a random sequence) are you are not intentionally calculating the information
252  to create a SHA-1 hash collision, then the probability that the sequences have
253  the same SHA-1 hash is approximately 2^-80 ~ 10^-24.
254 */
255 class ON_CLASS ON_SHA1
256 {
257 public:
258 
259  ON_SHA1() = default;
260  ~ON_SHA1() = default;
261  ON_SHA1(const ON_SHA1&) = default;
262  ON_SHA1& operator=(const ON_SHA1&) = default;
263 
264  /*
265  Description:
266  Make one or more calls to AccumulateBytes() as the sequenence of bytes is available.
267 
268  Parameters:
269  buffer - [in]
270  sizeof_buffer - [in]
271  number of bytes in buffer
272  */
273 #if defined(ON_COMPILER_MSC) && defined(NDEBUG)
274  // Reduces release build link time optimization by several hours for
275  // large programs that make lots of calls to ON_SHA1.Accumulate*() functions.
276  __declspec(noinline)
277 #endif
278  void AccumulateBytes(
279  const void* buffer,
280  ON__UINT64 sizeof_buffer
281  );
282 
283  /*
284  Description:
285  Add the double value to the SHA1 in a manner that
286  -0.0 and +0.0 will generate identical SHA-1 values
287  and the result is independent of endian byte order.
288  */
289  void AccumulateDouble(
290  double x
291  );
292 
293  /*
294  Description:
295  Add the double value to the SHA1 in a manner that
296  -0.0 and +0.0 will generate identical SHA-1 values
297  and the result is independent of endian byte order.
298  */
299  void AccumulateDoubleArray(
300  size_t count,
301  const double* a
302  );
303 
304  void Accumulate2dPoint(
305  const class ON_2dPoint& point
306  );
307 
308  void Accumulate3dPoint(
309  const class ON_3dPoint& point
310  );
311 
312  void Accumulate4dPoint(
313  const class ON_4dPoint& point
314  );
315 
316  void Accumulate2dVector(
317  const class ON_2dVector& vector
318  );
319 
320  void Accumulate3dVector(
321  const class ON_3dVector& vector
322  );
323 
324  void AccumulateBoundingBox(
325  const class ON_BoundingBox& bbox
326  );
327 
328  void AccumulateUnitSystem(
329  const class ON_UnitSystem& unit_system
330  );
331 
332  void AccumulateLengthUnitSystem(
333  const ON::LengthUnitSystem length_unit_system
334  );
335 
336  /*
337  Description:
338  Accumuates the full and relative path names.
339  */
340  void AccumulateFileReference(
341  const class ON_FileReference& file_reference
342  );
343 
344  void AccumulateTransformation(
345  const class ON_Xform& xform
346  );
347 
348  void AccumulateInteger8(
349  ON__INT8 i
350  );
351 
352  void AccumulateUnsigned8(
353  ON__UINT8 u
354  );
355 
356  void AccumulateInteger16(
357  ON__INT16 i
358  );
359 
360  void AccumulateUnsigned16(
361  ON__UINT16 u
362  );
363 
364  void AccumulateInteger32(
365  ON__INT32 i
366  );
367 
368  void AccumulateUnsigned32(
369  ON__UINT32 u
370  );
371 
372  void AccumulateInteger64(
373  ON__INT64 i
374  );
375 
376  void AccumulateUnsigned64(
377  ON__UINT64 u
378  );
379 
380 
381  void AccumulateBool(
382  bool b
383  );
384 
385 
386  void AccumulateString(
387  const class ON_String& str
388  );
389 
390  void AccumulateString(
391  const class ON_wString& str
392  );
393 
394  void AccumulateId(
395  const ON_UUID& id
396  );
397 
398  void AccumulateString(
399  const char* sUTF8,
400  int element_count,
401  ON_StringMapOrdinalType mapping
402  );
403 
404  void AccumulateString(
405  const wchar_t* sUTF8,
406  int element_count,
407  ON_StringMapOrdinalType mapping
408  );
409 
410  void AccumulateString(
411  const class ON_String& str,
412  ON_StringMapOrdinalType mapping
413  );
414 
415  void AccumulateString(
416  const class ON_wString& str,
417  ON_StringMapOrdinalType mapping
418  );
419 
420 
421  void AccumulateSubHash(
422  const class ON_SHA1_Hash& sub_hash
423  );
424 
425 private:
426  void Internal_SwapBigEndianUpdate(
427  const void* buffer,
428  ON__UINT64 sizeof_buffer
429  );
430 
431 public:
432  /*
433  Returns:
434  Total number of bytes passed to Update().
435  */
436  ON__UINT64 ByteCount() const;
437 
438  /*
439  Returns:
440  SHA-1 hash value of the sequenence of ByteCount() bytes that have been
441  passed to this ON_SHA1 classe's Update() function since construction
442  or the last call to Reset().
443  Remarks:
444  You may use Hash() to compute intermediate SHA-1 hash values.
445 
446  Put another way, you may call Update() zero or more times passing in N1 bytes,
447  call Digest() to get the SHA-1 hash of those N1 bytes, make zero or more additional
448  calls to Update() passing in N2 additional bytes, call digest to get the SHA-1 hash
449  of the seqence of (N1 + N2) bytes, and so on.
450  */
451  ON_SHA1_Hash Hash() const;
452 
453  /*
454  Description:
455  Reset this ON_SHA1 class so it can be reused.
456  */
457  void Reset();
458 
459  /*
460  Description:
461  This is a static function that uses ON_SHA1 to compute SHA-1 hash values
462  of sequences of bytes with known SHA-1 hash values and compares the
463  results from ON_SHA1 with the known SHA-1 hash values.
464 
465  This function can be used to validate the ON_SHA1 class compiled correctly.
466 
467  Returns:
468  true
469  All validation tests passed.
470  false
471  At least one validation test failed.
472  */
473  static bool Validate();
474 
475 private:
476  void Internal_Accumulate(const ON__UINT8* input, ON__UINT32 length);
477  void set_final_hash();
478 
479  ON__UINT64 m_byte_count = 0; // number of bytes that have passed through calls to update().
480  // if 1 == m_status_bits & 1, then update has been called at least once (perhaps with 0 bytes).
481  // if 2 == m_status_bits & 2, then m_sha1_hash is current.
482  mutable ON__UINT32 m_status_bits = 0;
483  ON__UINT32 m_reserved = 0;
484 
485  // current "remainder"
486  ON__UINT8 m_buffer[64]; // bytes that didn't fit in last 64 byte chunk
487  ON__UINT32 m_bit_count[2]; // number of bits (lo, hi)
488  ON__UINT32 m_state[5]; // current state
489 
490  // chached SHA1 hash - valid if 2 = (2 & m_status_bits)
491  mutable ON_SHA1_Hash m_sha1_hash;
492 };
493 
494 #endif
ON_UUID is a 16 byte universally unique identifier.
Definition: opennurbs_uuid.h:32
static const ON_SHA1_Hash EmptyContentHash
Definition: opennurbs_sha1.h:23
Definition: opennurbs_sha1.h:19
Definition: opennurbs_string.h:2020
Definition: opennurbs_point.h:277
Definition: opennurbs_point.h:648
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_string.h:852
Definition: opennurbs_xform.h:28
ON_SHA1 is a small class for calculating the SHA-1 hash of a sequence of bytes. It may be use increme...
Definition: opennurbs_sha1.h:242
Definition: opennurbs_string.h:3739
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
Definition: opennurbs_point.h:460
static const ON_SHA1_Hash ZeroDigest
Definition: opennurbs_sha1.h:22
Definition: opennurbs_point.h:839
Definition: opennurbs_point.h:1152
Definition: opennurbs_file_utilities.h:1125