123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- // This CRC function is based on Intel Slicing-by-8 algorithm.
- //
- // Original Intel Slicing-by-8 code is available here:
- //
- // http://sourceforge.net/projects/slicing-by-8/
- //
- // Original Intel Slicing-by-8 code is licensed as:
- //
- // Copyright (c) 2004-2006 Intel Corporation - All Rights Reserved
- //
- // This software program is licensed subject to the BSD License,
- // available at http://www.opensource.org/licenses/bsd-license.html
- #include "rar.hpp"
- #ifndef SFX_MODULE
- // User suggested to avoid BSD license in SFX module, so they do not need
- // to include the license to SFX archive.
- #define USE_SLICING
- #endif
- static uint crc_tables[8][256]; // Tables for Slicing-by-8.
- // Build the classic CRC32 lookup table.
- // We also provide this function to legacy RAR and ZIP decryption code.
- void InitCRC32(uint *CRCTab)
- {
- if (CRCTab[1]!=0)
- return;
- for (uint I=0;I<256;I++)
- {
- uint C=I;
- for (uint J=0;J<8;J++)
- C=(C & 1) ? (C>>1)^0xEDB88320 : (C>>1);
- CRCTab[I]=C;
- }
- }
- static void InitTables()
- {
- InitCRC32(crc_tables[0]);
- #ifdef USE_SLICING
- for (uint I=0;I<256;I++) // Build additional lookup tables.
- {
- uint C=crc_tables[0][I];
- for (uint J=1;J<8;J++)
- {
- C=crc_tables[0][(byte)C]^(C>>8);
- crc_tables[J][I]=C;
- }
- }
- #endif
- }
- struct CallInitCRC {CallInitCRC() {InitTables();}} static CallInit32;
- uint CRC32(uint StartCRC,const void *Addr,size_t Size)
- {
- byte *Data=(byte *)Addr;
- #ifdef USE_SLICING
- // Align Data to 8 for better performance.
- for (;Size>0 && ((size_t)Data & 7);Size--,Data++)
- StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
- for (;Size>=8;Size-=8,Data+=8)
- {
- #ifdef BIG_ENDIAN
- StartCRC ^= Data[0]|(Data[1] << 8)|(Data[2] << 16)|(Data[3] << 24);
- uint NextData = Data[4]|(Data[5] << 8)|(Data[6] << 16)|(Data[7] << 24);
- #else
- StartCRC ^= *(uint32 *) Data;
- uint NextData = *(uint32 *) (Data+4);
- #endif
- StartCRC = crc_tables[7][(byte) StartCRC ] ^
- crc_tables[6][(byte)(StartCRC >> 8) ] ^
- crc_tables[5][(byte)(StartCRC >> 16)] ^
- crc_tables[4][(byte)(StartCRC >> 24)] ^
- crc_tables[3][(byte) NextData ] ^
- crc_tables[2][(byte)(NextData >> 8) ] ^
- crc_tables[1][(byte)(NextData >> 16)] ^
- crc_tables[0][(byte)(NextData >> 24)];
- }
- #endif
- for (;Size>0;Size--,Data++) // Process left data.
- StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
- return StartCRC;
- }
- #ifndef SFX_MODULE
- // For RAR 1.4 archives in case somebody still has them.
- ushort Checksum14(ushort StartCRC,const void *Addr,size_t Size)
- {
- byte *Data=(byte *)Addr;
- for (size_t I=0;I<Size;I++)
- {
- StartCRC=(StartCRC+Data[I])&0xffff;
- StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff;
- }
- return StartCRC;
- }
- #endif
|