Tag.h
1 /* 2 * Copyright (c) 2013-2025, The PurpleI2P Project 3 * 4 * This file is part of Purple i2pd project and licensed under BSD3 5 * 6 * See full license text in LICENSE file at top of project tree 7 */ 8 9 #ifndef TAG_H__ 10 #define TAG_H__ 11 12 #include <boost/static_assert.hpp> 13 #include <string.h> 14 #include <openssl/rand.h> 15 #include <string> 16 #include <string_view> 17 #include "Base.h" 18 19 namespace i2p 20 { 21 namespace data 22 { 23 template<size_t sz> 24 class Tag 25 { 26 BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes"); 27 28 public: 29 30 Tag () = default; 31 Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); } 32 33 bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); } 34 bool operator!= (const Tag& other) const { return !(*this == other); } 35 bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; } 36 37 uint8_t * operator()() { return m_Buf; } 38 const uint8_t * operator()() const { return m_Buf; } 39 40 operator uint8_t * () { return m_Buf; } 41 operator const uint8_t * () const { return m_Buf; } 42 43 const uint8_t * data() const { return m_Buf; } 44 const uint64_t * GetLL () const { return ll; } 45 46 bool IsZero () const 47 { 48 for (size_t i = 0; i < sz/8; ++i) 49 if (ll[i]) return false; 50 return true; 51 } 52 53 void Fill(uint8_t c) 54 { 55 memset(m_Buf, c, sz); 56 } 57 58 void Randomize() 59 { 60 RAND_bytes(m_Buf, sz); 61 } 62 63 std::string ToBase64 (size_t len = sz) const 64 { 65 return i2p::data::ByteStreamToBase64 (m_Buf, len); 66 } 67 68 std::string ToBase32 (size_t len = sz) const 69 { 70 return i2p::data::ByteStreamToBase32 (m_Buf, len); 71 } 72 73 size_t FromBase32 (std::string_view s) 74 { 75 return i2p::data::Base32ToByteStream (s, m_Buf, sz); 76 } 77 78 size_t FromBase64 (std::string_view s) 79 { 80 return i2p::data::Base64ToByteStream (s, m_Buf, sz); 81 } 82 83 uint8_t GetBit (int i) const 84 { 85 int pos = i >> 3; // /8 86 if (pos >= (int)sz) return 0; 87 return m_Buf[pos] & (0x80 >> (i & 0x07)); 88 } 89 90 private: 91 92 union // 8 bytes aligned 93 { 94 uint8_t m_Buf[sz]; 95 uint64_t ll[sz/8]; 96 }; 97 }; 98 } // data 99 } // i2p 100 101 namespace std 102 { 103 // hash for std::unordered_map 104 template<size_t sz> struct hash<i2p::data::Tag<sz> > 105 { 106 size_t operator()(const i2p::data::Tag<sz>& s) const 107 { 108 return s.GetLL ()[0]; 109 } 110 }; 111 } 112 113 #endif /* TAG_H__ */