crc32.c 814 B

1234567891011121314151617181920212223242526272829303132333435
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <sys/types.h>
  3. #include <stdlib.h>
  4. #include <stdint.h>
  5. static uint32_t crc32_reverse(uint32_t x)
  6. {
  7. x = ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555);
  8. x = ((x & 0x33333333) << 2) | ((x >> 2) & 0x33333333);
  9. x = ((x & 0x0F0F0F0F) << 4) | ((x >> 4) & 0x0F0F0F0F);
  10. x = (x << 24) | ((x & 0xFF00) << 8) | ((x >> 8) & 0xFF00) | (x >> 24);
  11. return x;
  12. }
  13. uint32_t crc32(uint32_t iv, uint32_t sv, const void *data, size_t n)
  14. {
  15. const unsigned char *ptr;
  16. unsigned x;
  17. uint32_t byte, crc;
  18. crc = iv;
  19. ptr = data;
  20. while (n--) {
  21. byte = *ptr++;
  22. byte = crc32_reverse(byte);
  23. for (x = 0; x < 8; x++, byte <<= 1) crc = ((crc ^ byte) & 0x80000000U) ? (crc << 1) ^ sv : (crc << 1);
  24. }
  25. return crc;
  26. }
  27. uint32_t crc32_final(uint32_t iv)
  28. {
  29. return crc32_reverse(iv ^ ~0U);
  30. }