| Lasse Collin | 24fa040 | 2011-01-12 17:01:22 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * CRC32 using the polynomial from IEEE-802.3 | 
|  | 3 | * | 
|  | 4 | * Authors: Lasse Collin <lasse.collin@tukaani.org> | 
|  | 5 | *          Igor Pavlov <http://7-zip.org/> | 
|  | 6 | * | 
|  | 7 | * This file has been put into the public domain. | 
|  | 8 | * You can do whatever you want with this file. | 
|  | 9 | */ | 
|  | 10 |  | 
|  | 11 | /* | 
|  | 12 | * This is not the fastest implementation, but it is pretty compact. | 
|  | 13 | * The fastest versions of xz_crc32() on modern CPUs without hardware | 
|  | 14 | * accelerated CRC instruction are 3-5 times as fast as this version, | 
|  | 15 | * but they are bigger and use more memory for the lookup table. | 
|  | 16 | */ | 
|  | 17 |  | 
|  | 18 | #include "xz_private.h" | 
|  | 19 |  | 
|  | 20 | /* | 
|  | 21 | * STATIC_RW_DATA is used in the pre-boot environment on some architectures. | 
|  | 22 | * See <linux/decompress/mm.h> for details. | 
|  | 23 | */ | 
|  | 24 | #ifndef STATIC_RW_DATA | 
|  | 25 | #	define STATIC_RW_DATA static | 
|  | 26 | #endif | 
|  | 27 |  | 
|  | 28 | STATIC_RW_DATA uint32_t xz_crc32_table[256]; | 
|  | 29 |  | 
|  | 30 | XZ_EXTERN void xz_crc32_init(void) | 
|  | 31 | { | 
|  | 32 | const uint32_t poly = 0xEDB88320; | 
|  | 33 |  | 
|  | 34 | uint32_t i; | 
|  | 35 | uint32_t j; | 
|  | 36 | uint32_t r; | 
|  | 37 |  | 
|  | 38 | for (i = 0; i < 256; ++i) { | 
|  | 39 | r = i; | 
|  | 40 | for (j = 0; j < 8; ++j) | 
|  | 41 | r = (r >> 1) ^ (poly & ~((r & 1) - 1)); | 
|  | 42 |  | 
|  | 43 | xz_crc32_table[i] = r; | 
|  | 44 | } | 
|  | 45 |  | 
|  | 46 | return; | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | XZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) | 
|  | 50 | { | 
|  | 51 | crc = ~crc; | 
|  | 52 |  | 
|  | 53 | while (size != 0) { | 
|  | 54 | crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8); | 
|  | 55 | --size; | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | return ~crc; | 
|  | 59 | } |