118873b22SEugene Leviant //===--- CRC.cpp - Cyclic Redundancy Check implementation -----------------===//
218873b22SEugene Leviant //
318873b22SEugene Leviant // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
418873b22SEugene Leviant // See https://llvm.org/LICENSE.txt for license information.
518873b22SEugene Leviant // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
618873b22SEugene Leviant //
718873b22SEugene Leviant //===----------------------------------------------------------------------===//
818873b22SEugene Leviant //
91e1e3ba2SHans Wennborg // This file contains implementations of CRC functions.
101e1e3ba2SHans Wennborg //
111e1e3ba2SHans Wennborg // The implementation technique is the one mentioned in:
121e1e3ba2SHans Wennborg // D. V. Sarwate. 1988. Computation of cyclic redundancy checks via table
131e1e3ba2SHans Wennborg // look-up. Commun. ACM 31, 8 (August 1988)
141e1e3ba2SHans Wennborg //
151e1e3ba2SHans Wennborg // See also Ross N. Williams "A Painless Guide to CRC Error Detection
161e1e3ba2SHans Wennborg // Algorithms" (https://zlib.net/crc_v3.txt) or Hacker's Delight (2nd ed.)
171e1e3ba2SHans Wennborg // Chapter 14 (Figure 14-7 in particular) for how the algorithm works.
1818873b22SEugene Leviant //
1918873b22SEugene Leviant //===----------------------------------------------------------------------===//
2018873b22SEugene Leviant
2118873b22SEugene Leviant #include "llvm/Support/CRC.h"
221e1e3ba2SHans Wennborg
231e1e3ba2SHans Wennborg #include "llvm/ADT/ArrayRef.h"
2418873b22SEugene Leviant #include "llvm/Config/config.h"
2518873b22SEugene Leviant
2618873b22SEugene Leviant using namespace llvm;
2718873b22SEugene Leviant
28*31e5f712SPetr Hosek #if !LLVM_ENABLE_ZLIB
2918873b22SEugene Leviant
301e1e3ba2SHans Wennborg static const uint32_t CRCTable[256] = {
311e1e3ba2SHans Wennborg 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
321e1e3ba2SHans Wennborg 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
331e1e3ba2SHans Wennborg 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
341e1e3ba2SHans Wennborg 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
351e1e3ba2SHans Wennborg 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
361e1e3ba2SHans Wennborg 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
371e1e3ba2SHans Wennborg 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
381e1e3ba2SHans Wennborg 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
391e1e3ba2SHans Wennborg 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
401e1e3ba2SHans Wennborg 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
411e1e3ba2SHans Wennborg 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
421e1e3ba2SHans Wennborg 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
431e1e3ba2SHans Wennborg 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
441e1e3ba2SHans Wennborg 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
451e1e3ba2SHans Wennborg 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
461e1e3ba2SHans Wennborg 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
471e1e3ba2SHans Wennborg 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
481e1e3ba2SHans Wennborg 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
491e1e3ba2SHans Wennborg 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
501e1e3ba2SHans Wennborg 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
511e1e3ba2SHans Wennborg 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
521e1e3ba2SHans Wennborg 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
531e1e3ba2SHans Wennborg 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
541e1e3ba2SHans Wennborg 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
551e1e3ba2SHans Wennborg 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
561e1e3ba2SHans Wennborg 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
571e1e3ba2SHans Wennborg 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
581e1e3ba2SHans Wennborg 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
591e1e3ba2SHans Wennborg 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
601e1e3ba2SHans Wennborg 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
611e1e3ba2SHans Wennborg 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
621e1e3ba2SHans Wennborg 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
631e1e3ba2SHans Wennborg 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
641e1e3ba2SHans Wennborg 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
651e1e3ba2SHans Wennborg 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
661e1e3ba2SHans Wennborg 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
671e1e3ba2SHans Wennborg 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
681e1e3ba2SHans Wennborg 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
691e1e3ba2SHans Wennborg 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
701e1e3ba2SHans Wennborg 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
711e1e3ba2SHans Wennborg 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
721e1e3ba2SHans Wennborg 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
731e1e3ba2SHans Wennborg 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
7418873b22SEugene Leviant
crc32(uint32_t CRC,ArrayRef<uint8_t> Data)751e1e3ba2SHans Wennborg uint32_t llvm::crc32(uint32_t CRC, ArrayRef<uint8_t> Data) {
7618873b22SEugene Leviant CRC ^= 0xFFFFFFFFU;
771e1e3ba2SHans Wennborg for (uint8_t Byte : Data) {
781e1e3ba2SHans Wennborg int TableIdx = (CRC ^ Byte) & 0xff;
791e1e3ba2SHans Wennborg CRC = CRCTable[TableIdx] ^ (CRC >> 8);
8018873b22SEugene Leviant }
8118873b22SEugene Leviant return CRC ^ 0xFFFFFFFFU;
8218873b22SEugene Leviant }
831e1e3ba2SHans Wennborg
8418873b22SEugene Leviant #else
851e1e3ba2SHans Wennborg
8618873b22SEugene Leviant #include <zlib.h>
crc32(uint32_t CRC,ArrayRef<uint8_t> Data)871e1e3ba2SHans Wennborg uint32_t llvm::crc32(uint32_t CRC, ArrayRef<uint8_t> Data) {
886c4a8bc0SHans Wennborg // Zlib's crc32() only takes a 32-bit length, so we have to iterate for larger
896c4a8bc0SHans Wennborg // sizes. One could use crc32_z() instead, but that's a recent (2017) addition
906c4a8bc0SHans Wennborg // and may not be available on all systems.
916c4a8bc0SHans Wennborg do {
926c4a8bc0SHans Wennborg ArrayRef<uint8_t> Slice = Data.take_front(UINT32_MAX);
936c4a8bc0SHans Wennborg CRC = ::crc32(CRC, (const Bytef *)Slice.data(), (uInt)Slice.size());
946c4a8bc0SHans Wennborg Data = Data.drop_front(Slice.size());
956c4a8bc0SHans Wennborg } while (Data.size() > 0);
966c4a8bc0SHans Wennborg return CRC;
9718873b22SEugene Leviant }
981e1e3ba2SHans Wennborg
9918873b22SEugene Leviant #endif
1001e1e3ba2SHans Wennborg
crc32(ArrayRef<uint8_t> Data)1011e1e3ba2SHans Wennborg uint32_t llvm::crc32(ArrayRef<uint8_t> Data) { return crc32(0, Data); }
1021e1e3ba2SHans Wennborg
update(ArrayRef<uint8_t> Data)1031e1e3ba2SHans Wennborg void JamCRC::update(ArrayRef<uint8_t> Data) {
1041e1e3ba2SHans Wennborg CRC ^= 0xFFFFFFFFU; // Undo CRC-32 Init.
1051e1e3ba2SHans Wennborg CRC = crc32(CRC, Data);
1061e1e3ba2SHans Wennborg CRC ^= 0xFFFFFFFFU; // Undo CRC-32 XorOut.
1071e1e3ba2SHans Wennborg }
108