Skip to content

Instantly share code, notes, and snippets.

@tomilov
Last active January 30, 2018 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomilov/55a0c8f51892f67fec6304fa60adff89 to your computer and use it in GitHub Desktop.
Save tomilov/55a0c8f51892f67fec6304fa60adff89 to your computer and use it in GitHub Desktop.
CRC-32C
#pragma once
#include <cstdint>
#include <x86intrin.h>
inline
std::uint32_t crc32c(const void * input, std::size_t size, std::uint32_t result = ~0)
{
auto i8 = static_cast< const std::uint8_t * >(input);
auto count = std::min(size, (sizeof(std::uint32_t) - ((i8 - static_cast< decltype(i8) >(0)) % sizeof(std::uint32_t))) % sizeof(std::uint32_t));
for (std::size_t p = 0; p < count; ++p) {
result = _mm_crc32_u8(result, i8[p]);
}
i8 += count;
size -= count;
auto i32 = static_cast< const std::uint32_t * >(static_cast< const void * >(i8));
for (std::size_t p = 0; p < size / sizeof(std::uint32_t); ++p) {
result = _mm_crc32_u32(result, i32[p]);
}
i8 += size;
size %= sizeof(std::uint32_t);
i8 -= size;
for (std::size_t p = 0; p < size; ++p) {
result = _mm_crc32_u8(result, i8[p]);
}
return ~result; // crc32c({0xAB, 0x9B, 0xE0, 0x9B}) == 0, crc32c("DYB|O") == 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment