libcruft-util/hash/crc.hpp
Danny Robson f6056153e3 rename root namespace from util to cruft
This places, at long last, the core library code into the same namespace
as the extended library code.
2018-08-05 14:42:02 +10:00

70 lines
2.2 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2011-2018 Danny Robson <danny@nerdcruft.net>
*/
#ifndef CRUFT_UTIL_HASH_CRC_HPP
#define CRUFT_UTIL_HASH_CRC_HPP
#include "../view.hpp"
#include <array>
#include <cstdint>
#include <cstdlib>
#include <type_traits>
///////////////////////////////////////////////////////////////////////////////
namespace cruft::hash {
// Implements the crc checksum (from ethernet, png, etc).
//
// Adapted from the PNG specification (ISO/IEC 15948:2003), appendix D and
// the public domain implementation of Ross Williams.
//
// Generator: the polynomial, with the leading (ie, 32nd) high bit truncated.
// Initial: value used to initialise the digest
// Final: value to xor against the digest at finish time
// ReflectIn: whether to reverse the bits of each data byte
// ReflectOut: whether to reverse the bits of the digest at finish time
//
// Note that reflection isn't necessarily explicitly performed at update
// time. Instead we construct the lookup table appropriately to use the
// data values directly.
template <
typename DigestT,
DigestT Generator,
DigestT Initial,
DigestT Final,
bool ReflectIn,
bool ReflectOut
>
class crc {
public:
using digest_t = DigestT;
static constexpr auto generator = Generator;
digest_t operator() (cruft::view<const uint8_t*>) const noexcept;
static constexpr
std::array<DigestT,256>
table (void);
private:
static const std::array<DigestT,256> s_table;
};
using crc32 = crc<uint32_t, 0x04c11db7, 0xffffffff, 0xffffffff, true, true>;
using crc32b = crc<uint32_t, 0x04c11db7, 0xffffffff, 0xffffffff, false, false>;
using crc32c = crc<uint32_t, 0x1edc6f41, 0xffffffff, 0xffffffff, true, true>;
using crc32d = crc<uint32_t, 0xa833982b, 0xffffffff, 0xffffffff, true, true>;
using crc64 = crc<uint64_t, 0x42f0e1eba9ea3693, 0, 0, false, false>;
}
#endif