========================== How-To use CRC32 checksums ========================== You want to detect whether data has been corrupted? Good old CRC32 to the rescue! Basics ====== CRC32 calculates a 32 bit checksum over data; if a bit gets flipped in the data, you get a different checksum. Of course, this is not cryptographically secure, and collisions do occur -- but it's rare enough that as a checksum, CRC32 remains useful. We define two types: #. :cpp:type:`liberate::checksum::crc32_checksum` is platform dependent in size, but at least 32 bits long. It's an alias for ``std::uint_fast_32t`` and should be used for calculating sums. #. :cpp:type:`liberate::checksum::crc32_serialize` on the other hand is a 32-bit type that you can assign your calculated value to, and serialize it as only four bytes. .. sourcecode:: cpp :linenos: :dedent: :caption: CRC32 basics #include using namespace liberate::checksum; char buf1[] = { /* something */ }; std::vector buf2; // Initialize with something auto sum1 = crc32(buf1, buf1 + sizeof(buf1)); auto sum2 = crc32(buf2.begin(), buf2.end()); You just apply the :cpp:func:`liberate::checksum::crc32` function to some range, and it calculates the sum. The only constraint is that the range's value type is some 8 bit integer type. .. note:: As an implementation detail, the entire CRC32 lookup table is calculated *at compile time* as a ``constexpr`` value, meaning calculation of CRC32 checksums should yield about as compact code as you can get without dipping into assembly. No, there are no benchmarks. But if you run tests, let us know! Polynomials =========== So now you have a CRC32 checksum. Ahh, but *which* CRC32? Well, you can choose. CRC32 describes both an algorithm, and a polynomial to use in the algorithm, but people have used different polynomials for different purposes. This library defaults to the "normal" polynomial, as defined by ISO3309 and the IEEE 802.3 standards, and POSIX, etc. But there are a few more as you can see in :cpp:enum:`liberate::checksum::crc32_polynomials`. You just add the enum value as a third parameter: .. sourcecode:: cpp :linenos: :dedent: :caption: CRC32 polynomial selection auto sum1 = crc32(buf1, buf1 + sizeof(buf1)); auto sum2 = crc32(buf2.begin(), buf2.end(), CRC32_CASTAGNOLI); assert(sum1 != sum2); Serialization ============= Serialize CRC32 in 32 bits: .. sourcecode:: cpp :linenos: :dedent: :caption: CRC32 serialization crc32_serialize tmp = sum1; auto used = liberate::serialization::serialize_int(out, sizeof(out), tmp); .. seealso:: :doc:`serialization-integer`