diff options
author | Riccardo Spagni <ric@spagni.net> | 2019-03-05 16:21:30 +0200 |
---|---|---|
committer | Riccardo Spagni <ric@spagni.net> | 2019-03-05 16:21:30 +0200 |
commit | 5bbbe3902b4ee77ca1eb23edc0b5495812353b1f (patch) | |
tree | 16ab3b2aedec9e6b68ee8254434fbb937ecb37f3 /contrib/epee/src/hex.cpp | |
parent | Merge pull request #5119 (diff) | |
parent | epee: add SSL support (diff) | |
download | monero-5bbbe3902b4ee77ca1eb23edc0b5495812353b1f.tar.xz |
Merge pull request #4852
057c279c epee: add SSL support (Martijn Otto)
Diffstat (limited to 'contrib/epee/src/hex.cpp')
-rw-r--r-- | contrib/epee/src/hex.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/contrib/epee/src/hex.cpp b/contrib/epee/src/hex.cpp index 5c8acc8be..8421dcae9 100644 --- a/contrib/epee/src/hex.cpp +++ b/contrib/epee/src/hex.cpp @@ -83,4 +83,67 @@ namespace epee { return write_hex(out, src); } + + std::vector<uint8_t> from_hex::vector(boost::string_ref src) + { + // should we include a specific character + auto include = [](char input) { + // we ignore spaces and colons + return !std::isspace(input) && input != ':'; + }; + + // the number of relevant characters to decode + auto count = std::count_if(src.begin(), src.end(), include); + + // this must be a multiple of two, otherwise we have a truncated input + if (count % 2) { + throw std::length_error{ "Invalid hexadecimal input length" }; + } + + std::vector<uint8_t> result; + result.reserve(count / 2); + + // the data to work with (std::string is always null-terminated) + auto data = src.data(); + + // convert a single hex character to an unsigned integer + auto char_to_int = [](const char *input) { + switch (std::tolower(*input)) { + case '0': return 0; + case '1': return 1; + case '2': return 2; + case '3': return 3; + case '4': return 4; + case '5': return 5; + case '6': return 6; + case '7': return 7; + case '8': return 8; + case '9': return 9; + case 'a': return 10; + case 'b': return 11; + case 'c': return 12; + case 'd': return 13; + case 'e': return 14; + case 'f': return 15; + default: throw std::range_error{ "Invalid hexadecimal input" }; + } + }; + + // keep going until we reach the end + while (data[0] != '\0') { + // skip unwanted characters + if (!include(data[0])) { + ++data; + continue; + } + + // convert two matching characters to int + auto high = char_to_int(data++); + auto low = char_to_int(data++); + + result.push_back(high << 4 | low); + } + + return result; + } } |