From b39f80e606ed4bfec09064aaba50d77f82f1ff3f Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 13 Feb 2017 17:13:46 +1100 Subject: [PATCH] hash/crc: parameterise on type and polynomial generator --- hash/crc.cpp | 139 +++++++++++++++++++++++++++---------------------- hash/crc.hpp | 23 ++++++-- hash/fwd.hpp | 2 +- tools/hash.cpp | 2 +- 4 files changed, 97 insertions(+), 69 deletions(-) diff --git a/hash/crc.cpp b/hash/crc.cpp index 8bc7b27b..5fb659da 100644 --- a/hash/crc.cpp +++ b/hash/crc.cpp @@ -20,22 +20,90 @@ #include -using util::hash::crc32; +using util::hash::crc; /////////////////////////////////////////////////////////////////////////////// -static -std::array -make_table (void) +template +const std::array +crc::s_table = crc::table (); + + +/////////////////////////////////////////////////////////////////////////////// +template +crc::crc () noexcept { - std::array value {}; + reset (); +} + + +//----------------------------------------------------------------------------- +template +void +crc::reset (void) noexcept +{ + m_digest = 0; + m_digest = ~m_digest; +} + + +/////////////////////////////////////////////////////////////////////////////// +template +void +crc::update (const uint8_t *restrict first, + const uint8_t *restrict last) noexcept +{ + CHECK_LE (first, last); + + for (auto cursor = first; cursor != last; ++cursor) { + m_digest = s_table[*cursor ^ (m_digest & 0xFF)] ^ (m_digest >> 8u); + } +} + + +//----------------------------------------------------------------------------- +template +void +crc::update (const void *restrict _data, size_t len) noexcept +{ + auto data = reinterpret_cast (_data); + return update(data, data + len); +} + + +//----------------------------------------------------------------------------- +template +void +crc::finish (void) +{ + ; +} + + +//----------------------------------------------------------------------------- +template +DigestT +crc::digest (void) const +{ + return ~m_digest; +} + + +/////////////////////////////////////////////////////////////////////////////// +template +std::array +util::hash::crc::table (void) +{ + auto gen = Generator; + + std::array value {}; for (int i = 0; i < 256; ++i) { - std::uint32_t c = i; + digest_t c = i; for (int k = 0; k < 8; ++k) { if (c & 1) - c = 0xEDB88320L ^ (c >> 1); + c = gen ^ (c >> 1); else c >>= 1; } @@ -47,59 +115,6 @@ make_table (void) }; -//----------------------------------------------------------------------------- -static std::array table = make_table (); - - /////////////////////////////////////////////////////////////////////////////// -crc32::crc32 () noexcept -{ - reset (); -} - - -//----------------------------------------------------------------------------- -void -crc32::reset (void) noexcept -{ - m_digest = 0; - m_digest = ~m_digest; -} - - -/////////////////////////////////////////////////////////////////////////////// -void -crc32::update (const uint8_t *restrict first, - const uint8_t *restrict last) noexcept -{ - CHECK_LE (first, last); - - for (auto cursor = first; cursor != last; ++cursor) { - m_digest = table[*cursor ^ (m_digest & 0xFF)] ^ (m_digest >> 8u); - } -} - - -//----------------------------------------------------------------------------- -void -crc32::update (const void *restrict _data, size_t len) noexcept -{ - auto data = reinterpret_cast (_data); - return update(data, data + len); -} - - -//----------------------------------------------------------------------------- -void -crc32::finish (void) -{ - ; -} - - -//----------------------------------------------------------------------------- -typename crc32::digest_t -crc32::digest (void) const -{ - return ~m_digest; -} \ No newline at end of file +template class util::hash::crc; // png +//template class util::hash::crc; // ogg diff --git a/hash/crc.hpp b/hash/crc.hpp index 57ec9031..76e36228 100644 --- a/hash/crc.hpp +++ b/hash/crc.hpp @@ -17,19 +17,25 @@ #ifndef __UTIL_HASH_CRC_HPP #define __UTIL_HASH_CRC_HPP +#include #include #include +#include /////////////////////////////////////////////////////////////////////////////// namespace util::hash { - // Implements the crc32 checksum (from ethernet, png, etc). + // Implements the crc checksum (from ethernet, png, etc). // Adapted from the PNG specification (ISO/IEC 15948:2003), appendix D. - class crc32 { + template + class crc { public: - using digest_t = uint32_t; + static_assert (std::is_same::value, + "only 32 bit crc is supported at this time"); - crc32 () noexcept; + using digest_t = DigestT; + + crc () noexcept; void reset (void) noexcept; @@ -40,10 +46,17 @@ namespace util::hash { digest_t digest (void) const; + static + std::array + table (void); + private: digest_t m_digest; + + static const std::array s_table; }; + + using crc32 = crc; } #endif - diff --git a/hash/fwd.hpp b/hash/fwd.hpp index e8703dc2..b4fd9bee 100644 --- a/hash/fwd.hpp +++ b/hash/fwd.hpp @@ -34,7 +34,7 @@ namespace util::hash { class adler32; class bsdsum; class fletcher; - class crc32; + class crc; class xxhash; diff --git a/tools/hash.cpp b/tools/hash.cpp index 91c92556..9b47a04d 100644 --- a/tools/hash.cpp +++ b/tools/hash.cpp @@ -40,7 +40,7 @@ static const char* NAMES[] = { "adler32", "bsdsum", - "crc32", + "crc", "MD2", "MD4", "MD5",