1 #pragma once
2 
3 #include <array>
4 #include <cstddef>
5 #include <cstdint>
6 #include <string>
7 #include <vector>
8 
9 static constexpr std::array<char, 16> digitsArray = {
10     '0', '1', '2', '3', '4', '5', '6', '7',
11     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
12 
intToHexString(uint64_t value,size_t digits)13 inline std::string intToHexString(uint64_t value, size_t digits)
14 {
15     std::string rc(digits, '0');
16     size_t bitIndex = (digits - 1) * 4;
17     for (size_t digitIndex = 0; digitIndex < digits; digitIndex++)
18     {
19         rc[digitIndex] = digitsArray[(value >> bitIndex) & 0x0f];
20         bitIndex -= 4;
21     }
22     return rc;
23 }
24 
bytesToHexString(const std::vector<uint8_t> & bytes)25 inline std::string bytesToHexString(const std::vector<uint8_t>& bytes)
26 {
27     std::string rc(bytes.size() * 2, '0');
28     for (size_t i = 0; i < bytes.size(); ++i)
29     {
30         rc[i * 2] = digitsArray[(bytes[i] & 0xf0) >> 4];
31         rc[i * 2 + 1] = digitsArray[bytes[i] & 0x0f];
32     }
33     return rc;
34 }
35 
36 // Returns nibble.
hexCharToNibble(char ch)37 inline uint8_t hexCharToNibble(char ch)
38 {
39     uint8_t rc = 16;
40     if (ch >= '0' && ch <= '9')
41     {
42         rc = static_cast<uint8_t>(ch) - '0';
43     }
44     else if (ch >= 'A' && ch <= 'F')
45     {
46         rc = static_cast<uint8_t>(ch - 'A') + 10U;
47     }
48     else if (ch >= 'a' && ch <= 'f')
49     {
50         rc = static_cast<uint8_t>(ch - 'a') + 10U;
51     }
52 
53     return rc;
54 }
55 
56 // Returns empty vector in case of malformed hex-string.
hexStringToBytes(const std::string & str)57 inline std::vector<uint8_t> hexStringToBytes(const std::string& str)
58 {
59     std::vector<uint8_t> rc(str.size() / 2, 0);
60     for (size_t i = 0; i < str.length(); i += 2)
61     {
62         uint8_t hi = hexCharToNibble(str[i]);
63         if (i == str.length() - 1)
64         {
65             return {};
66         }
67         uint8_t lo = hexCharToNibble(str[i + 1]);
68         if (lo == 16 || hi == 16)
69         {
70             return {};
71         }
72 
73         rc[i / 2] = static_cast<uint8_t>(hi << 4) | lo;
74     }
75     return rc;
76 }
77