aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/src/hex.cpp
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2019-03-05 16:21:30 +0200
committerRiccardo Spagni <ric@spagni.net>2019-03-05 16:21:30 +0200
commit5bbbe3902b4ee77ca1eb23edc0b5495812353b1f (patch)
tree16ab3b2aedec9e6b68ee8254434fbb937ecb37f3 /contrib/epee/src/hex.cpp
parentMerge pull request #5119 (diff)
parentepee: add SSL support (diff)
downloadmonero-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.cpp63
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;
+ }
}