/* * 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