crc.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include <util/system/defaults.h>
  3. #define CRC16INIT 0
  4. #define CRC32INIT 0
  5. #define CRC64INIT ULL(0xFFFFFFFFFFFFFFFF)
  6. // CCITT CRC-16
  7. inline ui16 crc16(const char* buf, size_t buflen, ui32 crcinit = CRC16INIT) {
  8. ui32 crc = 0xFFFF & ((crcinit >> 8) ^ (crcinit << 8));
  9. const char* end = buf + buflen;
  10. extern const ui32* crctab16;
  11. while (buf < end) {
  12. crc = (crc >> 8) ^ crctab16[(crc ^ *buf) & 0xFF];
  13. ++buf;
  14. }
  15. return (ui16)(0xFFFF & ((crc >> 8) ^ (crc << 8)));
  16. }
  17. struct IdTR {
  18. Y_FORCE_INLINE static ui8 T(ui8 a) {
  19. return a;
  20. }
  21. };
  22. // CCITT CRC-32
  23. template <class TR>
  24. inline ui32 crc32(const char* buf, size_t buflen, ui32 crcinit = CRC32INIT) {
  25. ui32 crc = crcinit ^ 0xFFFFFFFF;
  26. const char* end = buf + buflen;
  27. extern const ui32* crctab32;
  28. while (buf < end) {
  29. crc = (crc >> 8) ^ crctab32[(crc ^ TR::T((ui8)*buf)) & 0xFF];
  30. ++buf;
  31. }
  32. return crc ^ 0xFFFFFFFF;
  33. }
  34. inline ui32 crc32(const char* buf, size_t buflen, ui32 crcinit = CRC32INIT) {
  35. return crc32<IdTR>(buf, buflen, crcinit);
  36. }
  37. inline ui32 crc32(const void* buf, size_t buflen, ui32 crcinit = CRC32INIT) {
  38. return crc32((const char*)buf, buflen, crcinit);
  39. }
  40. // Copyright (C) Sewell Development Corporation, 1994 - 1998.
  41. inline ui64 crc64(const void* buf, size_t buflen, ui64 crcinit = CRC64INIT) {
  42. const unsigned char* ptr = (const unsigned char*)buf;
  43. extern const ui64* crctab64;
  44. while (buflen--) {
  45. crcinit = crctab64[((crcinit >> 56) ^ *ptr++)] ^ (crcinit << 8);
  46. }
  47. return crcinit;
  48. }
  49. namespace NCrcPrivate {
  50. template <unsigned N>
  51. struct TCrcHelper;
  52. #define DEF_CRC_FUNC(t) \
  53. template <> \
  54. struct TCrcHelper<t> { \
  55. static const ui##t Init = CRC##t##INIT; \
  56. static inline ui##t Crc(const void* buf, size_t buflen, ui##t crcinit) { \
  57. return crc##t((const char*)buf, buflen, crcinit); \
  58. } \
  59. };
  60. DEF_CRC_FUNC(16)
  61. DEF_CRC_FUNC(32)
  62. DEF_CRC_FUNC(64)
  63. #undef DEF_CRC_FUNC
  64. }
  65. template <class T>
  66. static inline T Crc(const void* buf, size_t len, T init) {
  67. return (T)NCrcPrivate::TCrcHelper<8 * sizeof(T)>::Crc(buf, len, init);
  68. }
  69. template <class T>
  70. static inline T Crc(const void* buf, size_t len) {
  71. return Crc<T>(buf, len, (T)NCrcPrivate::TCrcHelper<8 * sizeof(T)>::Init);
  72. }