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