Last active
January 30, 2018 16:45
-
-
Save tomilov/55a0c8f51892f67fec6304fa60adff89 to your computer and use it in GitHub Desktop.
CRC-32C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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