1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-16 05:51:05 +01:00
nix/src/libutil/base-nix-32.cc
John Ericson 23c87d8a21 Encapsulate invalidBase32, avoid 0xFF magic number
This keeps things fast by making the function inline, but also prevents
people from having to know about the `0xFF` implementation detail
directly, instead making one go through a `std::optional` (which could be
fused away with a sufficiently smart compiler).

Additionally, the base "nix32" implementation is moved to its own header
file pair, as it is logically distinct and prior to the `Hash` data
type. It would probably be nice to do this with all the hash format
implementations.
2025-08-04 15:32:38 -04:00

42 lines
1,011 B
C++

#include <cassert>
#include "nix/util/base-nix-32.hh"
namespace nix {
constexpr const std::array<unsigned char, 256> BaseNix32::reverseMap = [] {
std::array<unsigned char, 256> map{};
for (size_t i = 0; i < map.size(); ++i)
map[i] = invalid; // invalid
for (unsigned char i = 0; i < 32; ++i)
map[static_cast<unsigned char>(characters[i])] = i;
return map;
}();
std::string BaseNix32::encode(std::span<const uint8_t> originalData)
{
if (originalData.size() == 0)
return {};
size_t len = encodedLength(originalData.size());
assert(len);
std::string s;
s.reserve(len);
for (int n = (int) len - 1; n >= 0; n--) {
unsigned int b = n * 5;
unsigned int i = b / 8;
unsigned int j = b % 8;
unsigned char c =
(originalData.data()[i] >> j) | (i >= originalData.size() - 1 ? 0 : originalData.data()[i + 1] << (8 - j));
s.push_back(characters[c & 0x1f]);
}
return s;
}
} // namespace nix