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