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 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 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. 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. 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