You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
- #pragma once
-
- #include <array>
- #include <cstddef>
- #include <string>
- #include <string_view>
-
- namespace browns {
-
- template <std::size_t N>
- std::string format_digest(const std::array<std::byte, N>& dig) {
- std::string ret;
- ret.resize(N * 2);
- for (std::size_t pos = 0; pos < N; ++pos) {
- std::byte b = dig[pos];
- char& c1 = ret[pos * 2];
- char& c2 = ret[pos * 2 + 1];
- const char tab[17] = "0123456789abcdef";
- auto high = (static_cast<char>(b) & 0xf0) >> 4;
- auto low = (static_cast<char>(b) & 0x0f);
- c1 = tab[high];
- c2 = tab[low];
- }
- return ret;
- }
-
- template <typename Digest>
- Digest parse_digest(std::string_view str) {
- Digest ret;
- std::byte* out_ptr = ret.data();
- std::byte* const out_end = out_ptr + ret.size();
- auto str_ptr = str.begin();
- const auto str_end = str.end();
-
- auto invalid = [&] { //
- throw std::runtime_error("Invalid hash digest string: " + std::string(str));
- };
-
- auto nibble = [&](char c) -> std::byte {
- if (c >= 'A' && c <= 'F') {
- c = static_cast<char>(c + ('a' - 'A'));
- }
- std::byte nib{0};
- if (c >= '0' && c <= '9') {
- nib = std::byte(c - '0');
- } else if (c >= 'a' && c <= 'f') {
- nib = std::byte(c - 'a');
- } else {
- invalid();
- }
- return nib;
- };
-
- // We must have an even number of chars to form full octets
- if (str.size() % 2) {
- invalid();
- }
-
- while (str_ptr != str_end && out_ptr != out_end) {
- std::byte high = nibble(*str_ptr++);
- std::byte low = nibble(*str_ptr++);
- std::byte octet = (high << 4) | low;
- *out_ptr++ = octet;
- }
-
- if (str_ptr != str_end || out_ptr != out_end) {
- invalid();
- }
- return ret;
- }
-
- } // namespace browns
|