Rizin
unix-like reverse engineering framework and cli tools
crc32_fast.c
Go to the documentation of this file.
1 //
11 //
12 // Author: Lasse Collin
13 //
14 // This file has been put into the public domain.
15 // You can do whatever you want with this file.
16 //
18 
19 #include "check.h"
20 #include "crc_macros.h"
21 
22 
23 // If you make any changes, do some benchmarking! Seemingly unrelated
24 // changes can very easily ruin the performance (and very probably is
25 // very compiler dependent).
27 lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)
28 {
29  crc = ~crc;
30 
31 #ifdef WORDS_BIGENDIAN
32  crc = bswap32(crc);
33 #endif
34 
35  if (size > 8) {
36  // Fix the alignment, if needed. The if statement above
37  // ensures that this won't read past the end of buf[].
38  while ((uintptr_t)(buf) & 7) {
39  crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);
40  --size;
41  }
42 
43  // Calculate the position where to stop.
44  const uint8_t *const limit = buf + (size & ~(size_t)(7));
45 
46  // Calculate how many bytes must be calculated separately
47  // before returning the result.
48  size &= (size_t)(7);
49 
50  // Calculate the CRC32 using the slice-by-eight algorithm.
51  while (buf < limit) {
52  crc ^= aligned_read32ne(buf);
53  buf += 4;
54 
55  crc = lzma_crc32_table[7][A(crc)]
56  ^ lzma_crc32_table[6][B(crc)]
57  ^ lzma_crc32_table[5][C(crc)]
58  ^ lzma_crc32_table[4][D(crc)];
59 
61  buf += 4;
62 
63  // At least with some compilers, it is critical for
64  // performance, that the crc variable is XORed
65  // between the two table-lookup pairs.
66  crc = lzma_crc32_table[3][A(tmp)]
67  ^ lzma_crc32_table[2][B(tmp)]
68  ^ crc
69  ^ lzma_crc32_table[1][C(tmp)]
70  ^ lzma_crc32_table[0][D(tmp)];
71  }
72  }
73 
74  while (size-- != 0)
75  crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);
76 
77 #ifdef WORDS_BIGENDIAN
78  crc = bswap32(crc);
79 #endif
80 
81  return ~crc;
82 }
#define A(x)
Definition: arc.h:165
#define B(x)
Definition: arc.h:166
#define C(x)
Definition: arc.h:167
#define D
Definition: block.c:38
Internal API to different integrity check functions.
const uint32_t lzma_crc32_table[8][256]
Definition: crc32_small.c:16
LZMA_API(uint32_t)
Definition: crc32_fast.c:26
Some endian-dependent macros for CRC32 and CRC64.
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
static uint32_t const uint8_t uint32_t uint32_t limit
Definition: memcmplen.h:45
#define S8(val)
int size_t
Definition: sftypes.h:40
unsigned int uint32_t
Definition: sftypes.h:29
unsigned char uint8_t
Definition: sftypes.h:31
_W64 unsigned int uintptr_t
#define bswap32(n)
static uint32_t aligned_read32ne(const uint8_t *buf)