Hash.hpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #ifndef ZT_HASH_HPP
  14. #define ZT_HASH_HPP
  15. #include "Constants.hpp"
  16. #include "TriviallyCopyable.hpp"
  17. namespace ZeroTier {
  18. /**
  19. * Container for cryptographic hashes
  20. *
  21. * The size of the hash used with this container must be a multiple of 64 bits.
  22. * Currently it's used as H<384> and H<512>.
  23. *
  24. * Warning: the [] operator is not bounds checked.
  25. *
  26. * @tparam BITS Bits in hash, must be a multiple of 64
  27. */
  28. template<unsigned int BITS>
  29. class Hash : public TriviallyCopyable
  30. {
  31. public:
  32. ZT_ALWAYS_INLINE Hash() noexcept {}
  33. /**
  34. * @param h Hash value of size BITS / 8
  35. */
  36. explicit ZT_ALWAYS_INLINE Hash(const void *h) noexcept { memcpy(_h,h,BITS / 8); }
  37. /**
  38. * @param h Hash value of size BITS / 8
  39. */
  40. ZT_ALWAYS_INLINE void set(const void *h) noexcept { memcpy(_h,h,BITS / 8); }
  41. ZT_ALWAYS_INLINE void zero() noexcept
  42. {
  43. for(int i=0;i<(BITS / sizeof(unsigned long));++i)
  44. _h[i] = 0;
  45. }
  46. ZT_ALWAYS_INLINE uint8_t *data() noexcept { return reinterpret_cast<uint8_t *>(_h); }
  47. ZT_ALWAYS_INLINE const uint8_t *data() const noexcept { return reinterpret_cast<const uint8_t *>(_h); }
  48. ZT_ALWAYS_INLINE uint8_t operator[](const unsigned int i) const noexcept { return reinterpret_cast<const uint8_t *>(_h)[i]; }
  49. ZT_ALWAYS_INLINE uint8_t &operator[](const unsigned int i) noexcept { return reinterpret_cast<uint8_t *>(_h)[i]; }
  50. static constexpr unsigned int size() noexcept { return BITS / 8; }
  51. ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return _h[0]; }
  52. ZT_ALWAYS_INLINE operator bool() const noexcept
  53. {
  54. for(int i=0;i<(BITS / sizeof(unsigned long));++i) {
  55. if (_h[i] != 0)
  56. return true;
  57. }
  58. return false;
  59. }
  60. ZT_ALWAYS_INLINE bool operator==(const Hash &h) const noexcept { return memcmp(_h,h._h,BITS / 8) == 0; }
  61. ZT_ALWAYS_INLINE bool operator!=(const Hash &h) const noexcept { return memcmp(_h,h._h,BITS / 8) != 0; }
  62. ZT_ALWAYS_INLINE bool operator<(const Hash &h) const noexcept { return memcmp(_h,h._h,BITS / 8) < 0; }
  63. ZT_ALWAYS_INLINE bool operator>(const Hash &h) const noexcept { return memcmp(_h,h._h,BITS / 8) > 0; }
  64. ZT_ALWAYS_INLINE bool operator<=(const Hash &h) const noexcept { return memcmp(_h,h._h,BITS / 8) <= 0; }
  65. ZT_ALWAYS_INLINE bool operator>=(const Hash &h) const noexcept { return memcmp(_h,h._h,BITS / 8) >= 0; }
  66. private:
  67. unsigned long _h[BITS / sizeof(unsigned long)];
  68. };
  69. } // namespace ZeroTier
  70. #endif