1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 /// \file crc64.c 4 /// \brief CRC64 calculation 5 /// 6 /// Calculate the CRC64 using the slice-by-four algorithm. This is the same 7 /// idea that is used in crc32_fast.c, but for CRC64 we use only four tables 8 /// instead of eight to avoid increasing CPU cache usage. 9 // 10 // Author: Lasse Collin 11 // 12 // This file has been put into the public domain. 13 // You can do whatever you want with this file. 14 // 15 /////////////////////////////////////////////////////////////////////////////// 16 17 #include "check.h" 18 #include "crc_macros.h" 19 20 21 #ifdef WORDS_BIGENDIAN 22 # define A1(x) ((x) >> 56) 23 #else 24 # define A1 A 25 #endif 26 27 28 // See the comments in crc32_fast.c. They aren't duplicated here. 29 extern LZMA_API(uint64_t) 30 lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc) 31 { 32 crc = ~crc; 33 34 #ifdef WORDS_BIGENDIAN 35 crc = bswap64(crc); 36 #endif 37 38 if (size > 4) { 39 while ((uintptr_t)(buf) & 3) { 40 crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc); 41 --size; 42 } 43 44 const uint8_t *const limit = buf + (size & ~(size_t)(3)); 45 size &= (size_t)(3); 46 47 while (buf < limit) { 48 #ifdef WORDS_BIGENDIAN 49 const uint32_t tmp = (crc >> 32) 50 ^ aligned_read32ne(buf); 51 #else 52 const uint32_t tmp = crc ^ aligned_read32ne(buf); 53 #endif 54 buf += 4; 55 56 crc = lzma_crc64_table[3][A(tmp)] 57 ^ lzma_crc64_table[2][B(tmp)] 58 ^ S32(crc) 59 ^ lzma_crc64_table[1][C(tmp)] 60 ^ lzma_crc64_table[0][D(tmp)]; 61 } 62 } 63 64 while (size-- != 0) 65 crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc); 66 67 #ifdef WORDS_BIGENDIAN 68 crc = bswap64(crc); 69 #endif 70 71 return ~crc; 72 } 73