Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

73 lines
1.9KB

  1. #pragma once
  2. #include <array>
  3. #include <cstddef>
  4. #include <string>
  5. #include <string_view>
  6. namespace browns {
  7. template <std::size_t N>
  8. std::string format_digest(const std::array<std::byte, N>& dig) {
  9. std::string ret;
  10. ret.resize(N * 2);
  11. for (std::size_t pos = 0; pos < N; ++pos) {
  12. std::byte b = dig[pos];
  13. char& c1 = ret[pos * 2];
  14. char& c2 = ret[pos * 2 + 1];
  15. const char tab[17] = "0123456789abcdef";
  16. auto high = (static_cast<char>(b) & 0xf0) >> 4;
  17. auto low = (static_cast<char>(b) & 0x0f);
  18. c1 = tab[high];
  19. c2 = tab[low];
  20. }
  21. return ret;
  22. }
  23. template <typename Digest>
  24. Digest parse_digest(std::string_view str) {
  25. Digest ret;
  26. std::byte* out_ptr = ret.data();
  27. std::byte* const out_end = out_ptr + ret.size();
  28. auto str_ptr = str.begin();
  29. const auto str_end = str.end();
  30. auto invalid = [&] { //
  31. throw std::runtime_error("Invalid hash digest string: " + std::string(str));
  32. };
  33. auto nibble = [&](char c) -> std::byte {
  34. if (c >= 'A' && c <= 'F') {
  35. c = static_cast<char>(c + ('a' - 'A'));
  36. }
  37. std::byte nib{0};
  38. if (c >= '0' && c <= '9') {
  39. nib = std::byte(c - '0');
  40. } else if (c >= 'a' && c <= 'f') {
  41. nib = std::byte(c - 'a');
  42. } else {
  43. invalid();
  44. }
  45. return nib;
  46. };
  47. // We must have an even number of chars to form full octets
  48. if (str.size() % 2) {
  49. invalid();
  50. }
  51. while (str_ptr != str_end && out_ptr != out_end) {
  52. std::byte high = nibble(*str_ptr++);
  53. std::byte low = nibble(*str_ptr++);
  54. std::byte octet = (high << 4) | low;
  55. *out_ptr++ = octet;
  56. }
  57. if (str_ptr != str_end || out_ptr != out_end) {
  58. invalid();
  59. }
  60. return ret;
  61. }
  62. } // namespace browns