srctree

Robin Linden parent cfb07a5d c0602025
util: Add a helper for generating crc32 checksums

inlinesplit
filename was Deleted added: 74, removed: 2, total 72
@@ -0,0 +1,47 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
#ifndef UTIL_CRC32_H_
#define UTIL_CRC32_H_
 
#include <array>
#include <cstdint>
#include <span>
 
namespace util {
 
// clang-format-14 really doesn't get along well with `requires`.
// clang-format off
 
// https://www.w3.org/TR/2022/WD-png-3-20221025/#5CRC-algorithm
template<typename T, std::size_t U = std::dynamic_extent>
requires(sizeof(T) == 1)
constexpr std::uint32_t crc32(std::span<T const, U> data) {
constexpr auto kCrcTable = [] {
std::array<std::uint32_t, 256> t{};
constexpr std::uint32_t kPolynomial = 0xEDB8'8320;
 
for (std::uint32_t i = 0; i < t.size(); ++i) {
std::uint32_t val = i;
 
for (std::uint32_t j = 0; j < 8; ++j) {
val = val & 1 ? kPolynomial ^ (val >> 1) : val >> 1;
}
 
t[i] = val;
}
 
return t;
}();
 
std::uint32_t crc{0xFFFF'FFFF};
for (auto byte : data) {
crc = kCrcTable[(crc ^ byte) & 0xFF] ^ crc >> 8;
}
return crc ^ 0xFFFF'FFFF;
}
 
} // namespace util
 
#endif
 
filename was Deleted added: 74, removed: 2, total 72
@@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2023 Robin Lindén <dev@robinlinden.eu>
//
// SPDX-License-Identifier: BSD-2-Clause
 
#include "util/crc32.h"
 
#include "etest/etest.h"
 
#include <span>
#include <string_view>
 
using namespace std::literals;
using etest::expect_eq;
 
int main() {
etest::test("no data", [] { expect_eq(util::crc32(std::span{""sv}), 0u); });
 
etest::test("data", [] {
// crc32 <(echo -n "The quick brown fox jumps over the lazy dog")
auto data = "The quick brown fox jumps over the lazy dog"sv;
expect_eq(util::crc32(std::span{data}), 0x414fa339u);
});
 
return etest::run_all_tests();
}