xref: /openbmc/bmcweb/features/redfish/include/utils/hex_utils.hpp (revision d5c80ad9c07b94465d8ea62d2b6f87c30cac765e)
1f201ffb4SEd Tanous #pragma once
2f201ffb4SEd Tanous 
3f201ffb4SEd Tanous #include <array>
49ea15c35SEd Tanous #include <cstddef>
5*d5c80ad9SNan Zhou #include <cstdint>
6f201ffb4SEd Tanous #include <string>
74cee35e7SVidya Satyamsetti #include <vector>
8f201ffb4SEd Tanous 
9f201ffb4SEd Tanous static constexpr std::array<char, 16> digitsArray = {
10f201ffb4SEd Tanous     '0', '1', '2', '3', '4', '5', '6', '7',
11f201ffb4SEd Tanous     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
124cee35e7SVidya Satyamsetti 
134cee35e7SVidya Satyamsetti inline std::string intToHexString(uint64_t value, size_t digits)
144cee35e7SVidya Satyamsetti {
15f201ffb4SEd Tanous     std::string rc(digits, '0');
16f201ffb4SEd Tanous     size_t bitIndex = (digits - 1) * 4;
17f201ffb4SEd Tanous     for (size_t digitIndex = 0; digitIndex < digits; digitIndex++)
18f201ffb4SEd Tanous     {
19f201ffb4SEd Tanous         rc[digitIndex] = digitsArray[(value >> bitIndex) & 0x0f];
20f201ffb4SEd Tanous         bitIndex -= 4;
21f201ffb4SEd Tanous     }
22f201ffb4SEd Tanous     return rc;
23f201ffb4SEd Tanous }
244cee35e7SVidya Satyamsetti 
254cee35e7SVidya Satyamsetti inline std::string bytesToHexString(const std::vector<uint8_t>& bytes)
264cee35e7SVidya Satyamsetti {
274cee35e7SVidya Satyamsetti     std::string rc(bytes.size() * 2, '0');
284cee35e7SVidya Satyamsetti     for (size_t i = 0; i < bytes.size(); ++i)
294cee35e7SVidya Satyamsetti     {
304cee35e7SVidya Satyamsetti         rc[i * 2] = digitsArray[(bytes[i] & 0xf0) >> 4];
314cee35e7SVidya Satyamsetti         rc[i * 2 + 1] = digitsArray[bytes[i] & 0x0f];
324cee35e7SVidya Satyamsetti     }
334cee35e7SVidya Satyamsetti     return rc;
344cee35e7SVidya Satyamsetti }
354cee35e7SVidya Satyamsetti 
364cee35e7SVidya Satyamsetti // Returns nibble.
374cee35e7SVidya Satyamsetti inline uint8_t hexCharToNibble(char ch)
384cee35e7SVidya Satyamsetti {
394cee35e7SVidya Satyamsetti     uint8_t rc = 16;
404cee35e7SVidya Satyamsetti     if (ch >= '0' && ch <= '9')
414cee35e7SVidya Satyamsetti     {
424cee35e7SVidya Satyamsetti         rc = static_cast<uint8_t>(ch) - '0';
434cee35e7SVidya Satyamsetti     }
444cee35e7SVidya Satyamsetti     else if (ch >= 'A' && ch <= 'F')
454cee35e7SVidya Satyamsetti     {
464cee35e7SVidya Satyamsetti         rc = static_cast<uint8_t>(ch) - 'A' + 10;
474cee35e7SVidya Satyamsetti     }
484cee35e7SVidya Satyamsetti     else if (ch >= 'a' && ch <= 'f')
494cee35e7SVidya Satyamsetti     {
504cee35e7SVidya Satyamsetti         rc = static_cast<uint8_t>(ch) - 'a' + 10;
514cee35e7SVidya Satyamsetti     }
524cee35e7SVidya Satyamsetti 
534cee35e7SVidya Satyamsetti     return rc;
544cee35e7SVidya Satyamsetti }
554cee35e7SVidya Satyamsetti 
564cee35e7SVidya Satyamsetti // Returns empty vector in case of malformed hex-string.
574cee35e7SVidya Satyamsetti inline std::vector<uint8_t> hexStringToBytes(const std::string& str)
584cee35e7SVidya Satyamsetti {
594cee35e7SVidya Satyamsetti     std::vector<uint8_t> rc(str.size() / 2, 0);
604cee35e7SVidya Satyamsetti     for (size_t i = 0; i < str.length(); i += 2)
614cee35e7SVidya Satyamsetti     {
624cee35e7SVidya Satyamsetti         uint8_t hi = hexCharToNibble(str[i]);
634cee35e7SVidya Satyamsetti         if (i == str.length() - 1)
644cee35e7SVidya Satyamsetti         {
654cee35e7SVidya Satyamsetti             return {};
664cee35e7SVidya Satyamsetti         }
674cee35e7SVidya Satyamsetti         uint8_t lo = hexCharToNibble(str[i + 1]);
684cee35e7SVidya Satyamsetti         if (lo == 16 || hi == 16)
694cee35e7SVidya Satyamsetti         {
704cee35e7SVidya Satyamsetti             return {};
714cee35e7SVidya Satyamsetti         }
724cee35e7SVidya Satyamsetti 
734cee35e7SVidya Satyamsetti         rc[i / 2] = static_cast<uint8_t>(hi << 4) | lo;
744cee35e7SVidya Satyamsetti     }
754cee35e7SVidya Satyamsetti     return rc;
764cee35e7SVidya Satyamsetti }
77