├── library.properties ├── library.json ├── examples ├── cpp │ ├── one_time.cpp │ └── continuous.cpp └── arduino │ ├── one_time │ └── one_time.ino │ ├── continuous │ └── continuous.ino │ └── continuous_reset │ └── continuous_reset.ino ├── LICENSE ├── libs └── CRCpp │ ├── LICENSE │ ├── README.md │ └── CRC.h ├── .github └── workflows │ └── build.yml ├── README.md └── CRCx.h /library.properties: -------------------------------------------------------------------------------- 1 | name=CRCx 2 | version=0.4.0 3 | author=hideakitai 4 | maintainer=hideakitai 5 | sentence=CRC calculation for Arduino and other C++ programs 6 | paragraph=CRC calculation for Arduino and other C++ programs 7 | category=Data Processing 8 | url=https://github.com/hideakitai 9 | architectures=* 10 | depends=FastCRC 11 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CRCx", 3 | "keywords": "crc, utility", 4 | "description": "CRC calculation for Arduino and other C++ programs", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/hideakitai/CRCx.git" 9 | }, 10 | "authors": 11 | { 12 | "name": "Hideaki Tai", 13 | "url": "https://github.com/hideakitai", 14 | "maintainer": true 15 | }, 16 | "version": "0.4.0", 17 | "license": "MIT", 18 | "frameworks": "*", 19 | "platforms": "*", 20 | "dependencies": 21 | { 22 | "FrankBoesing/FastCRC": "*" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/cpp/one_time.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../src/CRCx.h" 3 | 4 | const uint8_t data[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; 5 | const size_t size = sizeof(data); 6 | 7 | int main() { 8 | uint8_t result8 = crcx::crc8(data, size); 9 | uint16_t result16 = crcx::crc16(data, size); 10 | uint32_t result32 = crcx::crc32(data, size); 11 | 12 | std::cout << "crc8 = 0x" << std::hex << (int)result8 << std::endl; 13 | std::cout << "crc16 = 0x" << std::hex << result16 << std::endl; 14 | std::cout << "crc32 = 0x" << std::hex << result32 << std::endl; 15 | 16 | return 0; 17 | } 18 | 19 | // Output: 20 | // crc8 = 0x7 21 | // crc16 = 0xB944 22 | // crc32 = 0x87E5865B 23 | -------------------------------------------------------------------------------- /examples/arduino/one_time/one_time.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const uint8_t data[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; 4 | const size_t size = sizeof(data); 5 | 6 | void setup() { 7 | Serial.begin(115200); 8 | delay(2000); 9 | 10 | uint8_t result8 = crcx::crc8(data, size); 11 | uint16_t result16 = crcx::crc16(data, size); 12 | uint32_t result32 = crcx::crc32(data, size); 13 | 14 | Serial.print("crc8 = 0x"); 15 | Serial.println(result8, HEX); 16 | Serial.print("crc16 = 0x"); 17 | Serial.println(result16, HEX); 18 | Serial.print("crc32 = 0x"); 19 | Serial.println(result32, HEX); 20 | } 21 | 22 | void loop() { 23 | } 24 | 25 | // Output: 26 | // crc8 = 0x7 27 | // crc16 = 0xB944 28 | // crc32 = 0x87E5865B 29 | -------------------------------------------------------------------------------- /examples/cpp/continuous.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "../../src/CRCx.h" 3 | 4 | const uint8_t data[11] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; 5 | const size_t size = sizeof(data); 6 | 7 | int main() { 8 | // first 9 | uint8_t result8 = crcx::crc8_update(data, 5); 10 | uint16_t result16 = crcx::crc16_update(data, 5); 11 | uint32_t result32 = crcx::crc32_update(data, 5); 12 | 13 | // second 14 | result8 = crcx::crc8_update(data + 5, 3); 15 | result16 = crcx::crc16_update(data + 5, 3); 16 | result32 = crcx::crc32_update(data + 5, 3); 17 | 18 | // third 19 | result8 = crcx::crc8_update(data + 8, 3); 20 | result16 = crcx::crc16_update(data + 8, 3); 21 | result32 = crcx::crc32_update(data + 8, 3); 22 | 23 | std::cout << "crc8 = 0x" << std::hex << (int)result8 << std::endl; 24 | std::cout << "crc16 = 0x" << std::hex << result16 << std::endl; 25 | std::cout << "crc32 = 0x" << std::hex << result32 << std::endl; 26 | 27 | return 0; 28 | } 29 | 30 | // Output: 31 | // crc8 = 0x7 32 | // crc16 = 0xB944 33 | // crc32 = 0x87E5865B 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Hideaki Tai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/arduino/continuous/continuous.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const uint8_t data[11] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; 4 | const size_t size = sizeof(data); 5 | 6 | void setup() { 7 | Serial.begin(115200); 8 | delay(2000); 9 | 10 | // first 11 | uint8_t result8 = crcx::crc8_update(data, 5); 12 | uint16_t result16 = crcx::crc16_update(data, 5); 13 | uint32_t result32 = crcx::crc32_update(data, 5); 14 | 15 | // second 16 | result8 = crcx::crc8_update(data + 5, 3); 17 | result16 = crcx::crc16_update(data + 5, 3); 18 | result32 = crcx::crc32_update(data + 5, 3); 19 | 20 | // third 21 | result8 = crcx::crc8_update(data + 8, 3); 22 | result16 = crcx::crc16_update(data + 8, 3); 23 | result32 = crcx::crc32_update(data + 8, 3); 24 | 25 | Serial.print("crc8 = 0x"); 26 | Serial.println(result8, HEX); 27 | Serial.print("crc16 = 0x"); 28 | Serial.println(result16, HEX); 29 | Serial.print("crc32 = 0x"); 30 | Serial.println(result32, HEX); 31 | } 32 | 33 | void loop() { 34 | } 35 | 36 | // Output: 37 | // crc8 = 0x7 38 | // crc16 = 0xB944 39 | // crc32 = 0x87E5865B 40 | -------------------------------------------------------------------------------- /examples/arduino/continuous_reset/continuous_reset.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const uint8_t data[11] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; 4 | const size_t size = sizeof(data); 5 | 6 | void setup() { 7 | Serial.begin(115200); 8 | delay(2000); 9 | 10 | // first 11 | uint8_t result8 = crcx::crc8_update(data, 5); 12 | uint16_t result16 = crcx::crc16_update(data, 5); 13 | uint32_t result32 = crcx::crc32_update(data, 5); 14 | 15 | // second 16 | result8 = crcx::crc8_update(data + 5, 3); 17 | result16 = crcx::crc16_update(data + 5, 3); 18 | result32 = crcx::crc32_update(data + 5, 3); 19 | 20 | // third 21 | result8 = crcx::crc8_update(data + 8, 3); 22 | result16 = crcx::crc16_update(data + 8, 3); 23 | result32 = crcx::crc32_update(data + 8, 3); 24 | 25 | Serial.print("crc8 = 0x"); 26 | Serial.println(result8, HEX); 27 | Serial.print("crc16 = 0x"); 28 | Serial.println(result16, HEX); 29 | Serial.print("crc32 = 0x"); 30 | Serial.println(result32, HEX); 31 | } 32 | 33 | void loop() { 34 | } 35 | 36 | // Output: 37 | // crc8 = 0x7 38 | // crc16 = 0xB944 39 | // crc32 = 0x87E5865B 40 | -------------------------------------------------------------------------------- /libs/CRCpp/LICENSE: -------------------------------------------------------------------------------- 1 | CRC++ 2 | Copyright (c) 2021, Daniel Bahr 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | * Neither the name of CRC++ nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | - develop 6 | paths-ignore: 7 | - .git* 8 | - '**.md' 9 | - 'library.properties' 10 | - 'library.json' 11 | pull_request: 12 | branches: 13 | - main 14 | - develop 15 | paths-ignore: 16 | - .git* 17 | - '**.md' 18 | - 'library.properties' 19 | - 'library.json' 20 | 21 | jobs: 22 | build: 23 | name: 'Build Test: ${{matrix.board.arch}}:${{matrix.board.name}}' 24 | runs-on: ubuntu-latest 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | board: 29 | - vendor: arduino 30 | arch: avr 31 | name: uno 32 | - vendor: arduino 33 | arch: megaavr 34 | name: uno2018 35 | - vendor: arduino 36 | arch: samd 37 | name: mkrvidor4000 38 | - vendor: arduino 39 | arch: samd 40 | name: mkrwifi1010 41 | - vendor: arduino 42 | arch: samd 43 | name: mkr1000 44 | - vendor: arduino 45 | arch: samd 46 | name: nano_33_iot 47 | - vendor: esp8266 48 | arch: esp8266 49 | name: generic 50 | - vendor: esp32 51 | arch: esp32 52 | name: esp32 53 | - vendor: esp32 54 | arch: esp32 55 | name: esp32s3 56 | - vendor: esp32 57 | arch: esp32 58 | name: esp32c3 59 | - vendor: rp2040 60 | arch: rp2040 61 | name: rpipicow 62 | - vendor: teensy 63 | arch: avr 64 | name: teensy35 65 | - vendor: teensy 66 | arch: avr 67 | name: teensy36 68 | - vendor: teensy 69 | arch: avr 70 | name: teensy41 71 | include: 72 | - index: https://downloads.arduino.cc/packages/package_index.json 73 | board: 74 | vendor: arduino 75 | - index: https://arduino.esp8266.com/stable/package_esp8266com_index.json 76 | board: 77 | vendor: esp8266 78 | - index: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json 79 | board: 80 | vendor: esp32 81 | - index: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json 82 | board: 83 | vendor: rp2040 84 | - index: https://www.pjrc.com/teensy/package_teensy_index.json 85 | board: 86 | vendor: teensy 87 | steps: 88 | - uses: actions/checkout@v4 89 | - name: compile example sketchs 90 | uses: arduino/compile-sketches@v1 91 | with: 92 | github-token: ${{ secrets.GITHUB_TOKEN }} 93 | fqbn: ${{matrix.board.vendor}}:${{matrix.board.arch}}:${{matrix.board.name}} 94 | platforms: | 95 | - name: ${{matrix.board.vendor}}:${{matrix.board.arch}} 96 | source-url: ${{matrix.index}} 97 | sketch-paths: | 98 | - examples 99 | libraries: | 100 | - source-path: ./ 101 | - name: FastCRC 102 | verbose: true 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CRCx 2 | 3 | CRC calculation for Arduino and other C++ programs. 4 | This library is created to use crc calculation as same method for both Arduino and other C++ propgrams (like openFrameworks and so on). 5 | CRCx is based on fast and efficient two great works, and CRCx is just a glue for these two great works. 6 | 7 | - [FastCRC](https://github.com/FrankBoesing/FastCRC) by @FrankBoesing for Arduino 8 | - [CRCpp](https://github.com/d-bahr/CRCpp) v1.1.0.0 by @d-bahr for other C++ programs 9 | 10 | 11 | ## Usage 12 | 13 | ### One-Time calculation 14 | 15 | ``` C++ 16 | #include 17 | 18 | const uint8_t data[] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; 19 | const size_t size = sizeof(data); 20 | 21 | void setup() { 22 | Serial.begin(115200); 23 | delay(2000); 24 | 25 | uint8_t result8 = crcx::crc8(data, size); 26 | uint16_t result16 = crcx::crc16(data, size); 27 | uint32_t result32 = crcx::crc32(data, size); 28 | 29 | Serial.print("crc8 = 0x"); Serial.println(result8, HEX); 30 | Serial.print("crc16 = 0x"); Serial.println(result16, HEX); 31 | Serial.print("crc32 = 0x"); Serial.println(result32, HEX); 32 | } 33 | 34 | // Console Output: 35 | // crc8 = 0x7 36 | // crc16 = 0xB944 37 | // crc32 = 0x87E5865B 38 | 39 | ``` 40 | 41 | ### Continuous calculation 42 | 43 | ```C++ 44 | #include 45 | 46 | const uint8_t data[11] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D'}; 47 | const size_t size = sizeof(data); 48 | 49 | void setup() { 50 | Serial.begin(115200); 51 | delay(2000); 52 | 53 | // first 54 | uint8_t result8 = crcx::crc8_update(data, 5); 55 | uint16_t result16 = crcx::crc16_update(data, 5); 56 | uint32_t result32 = crcx::crc32_update(data, 5); 57 | 58 | // second 59 | result8 = crcx::crc8_update(data + 5, 3); 60 | result16 = crcx::crc16_update(data + 5, 3); 61 | result32 = crcx::crc32_update(data + 5, 3); 62 | 63 | // third 64 | result8 = crcx::crc8_update(data + 8, 3); 65 | result16 = crcx::crc16_update(data + 8, 3); 66 | result32 = crcx::crc32_update(data + 8, 3); 67 | 68 | Serial.print("crc8 = 0x"); Serial.println(result8, HEX); 69 | Serial.print("crc16 = 0x"); Serial.println(result16, HEX); 70 | Serial.print("crc32 = 0x"); Serial.println(result32, HEX); 71 | } 72 | 73 | // Output: 74 | // crc8 = 0x7 75 | // crc16 = 0xB944 76 | // crc32 = 0x87E5865B 77 | ``` 78 | 79 | ## APIs 80 | 81 | ```C++ 82 | inline uint8_t crc8(const uint8_t* data, const size_t size, const Crc8 type = Crc8::SMBUS); 83 | inline uint16_t crc16(const uint8_t* data, const size_t size, const Crc16 type = Crc16::MODBUS); 84 | inline uint32_t crc32(const uint8_t* data, const size_t size, const Crc32 type = Crc32::CRC32); 85 | inline uint8_t crc8_update(const uint8_t* data, const size_t size, const Crc8 type = Crc8::SMBUS); 86 | inline uint16_t crc16_update(const uint8_t* data, const size_t size, const Crc16 type = Crc16::MODBUS); 87 | inline uint32_t crc32_update(const uint8_t* data, const size_t size, const Crc32 type = Crc32::CRC32); 88 | 89 | // C++ (not Arduino) Only 90 | inline uint64_t crc64(const uint8_t* data, const size_t size); 91 | inline uint64_t crc64_update(const uint8_t* data, const size_t size); 92 | ``` 93 | 94 | ## CRC Options 95 | 96 | You can specify how to calculate by setting 3rd argument. 97 | 98 | ``` C++ 99 | uint32_t result32 = crcx::crc32(data, size, Crc32::POSIX); 100 | ``` 101 | 102 | Available options and default parameters are shown below. 103 | 104 | ``` C++ 105 | enum class Crc8 : uint8_t { 106 | SMBUS, // default 107 | MAXIM 108 | }; 109 | 110 | enum class Crc16 : uint8_t { 111 | CCITT, 112 | KERMIT, 113 | MODBUS, // default 114 | XMODEM, 115 | X25 116 | }; 117 | 118 | enum class Crc32 : uint8_t { 119 | CRC32, // default 120 | POSIX 121 | }; 122 | ``` 123 | 124 | ## Use `FastCRC` or `CRCpp` directly 125 | 126 | Of course, you can use `FastCRC` or `CRCpp` directly. 127 | 128 | ### FastCRC 129 | 130 | ``` C++ 131 | FastCRC32 fastcrc; 132 | uint32_t crc32 = fastcrc.crc32(data, size); 133 | ``` 134 | 135 | Please refer to [FastCRC original page](https://github.com/FrankBoesing/FastCRC) for more information. 136 | 137 | ### CRCpp 138 | 139 | NOTE: Following `CRCpp` options are enabled as default. 140 | 141 | ```C++ 142 | #define CRCPP_USE_CPP11 143 | #define CRCPP_USE_NAMESPACE 144 | #define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 145 | ``` 146 | 147 | and you can use as: 148 | 149 | ``` C++ 150 | uint32_t crc32 = CRCpp::CRC::Calculate(data, size, CRCpp::CRC::CRC_32()); 151 | ``` 152 | 153 | Please refer to [CRCpp original page](https://github.com/d-bahr/CRCpp) for more information. 154 | 155 | ## License 156 | 157 | MIT 158 | -------------------------------------------------------------------------------- /libs/CRCpp/README.md: -------------------------------------------------------------------------------- 1 | # CRC++ 2 | Easy to use and fast C++ CRC library. 3 | 4 | Tired of writing CRC code over and over again? Don't want to include a dozen boost header files just for a little bit of functionality? CRC++ is a portable and extremely lightweight alternative that is incredibly simple, fast, and clean. 5 | 6 | ### Features 7 | 8 | CRC++ supports bit-by-bit and byte-by-byte calculation of full and multipart CRCs. The algorithms used are highly optimized and can even be configured to be branchless (as always, be sure to profile your code to choose the most efficient option). CRC++ is a great option for embedded C++ projects with a need for efficiency. 9 | 10 | CRC++ consists of a single header file which can be included in any existing C++ application. No libraries, no boost, no mess, no fuss. 11 | 12 | Any CRC width is supported - even CRCs larger than 64 bits, provided there is an integer type large enough to contain it. Trying to compute a 57-bit CRC? Got you covered. 13 | 14 | Many common CRCs are provided out-of-the-box, such as CRC-32 (used in PKZip and Ethernet), CRC-XMODEM, and CRC-CCITT. 15 | 16 | CRC++ will compile with any reasonably compliant C++03 or C++11 compiler. Compiling with C++11 is recommended, as it allows a number of static computations to be performed at compile-time instead of runtime. 17 | 18 | All of the CRC++ code is well-documented. Unit tests are included in the repository (g++ Makefile and Visual Studio 2015 projects included). HTML documentation can also be produced via Doxygen (also included in the repository). 19 | 20 | ### Comparison 21 | 22 | CRC++ boasts one of the fastest and most memory efficient generic CRC implementation available. The below table shows performance comparisons across multiple implementations and platforms. 23 | 24 | | Library | Speed, x64 platform (100 million iterations) | Speed, x86 platform (100 million iterations) | 25 | | ------------- | -------------------------------------------- | -------------------------------------------- | 26 | | CRC++ | 2050 milliseconds | 2200 milliseconds | 27 | | boost | 2250 milliseconds | 2000 milliseconds | 28 | | pycrc | 2050 milliseconds | 2240 milliseconds | 29 | | mhash | 2250 milliseconds | 2400 milliseconds | 30 | 31 | Additionally, CRC++ has the most features of any library and the smallest code footprint: 32 | 33 | | Library | Number of include files | Header-only implemen-tation | Supports byte != 8 bits | Supports arbitrary CRC width | Custom type support | C++11 support | 40+ built-in CRC definitions | Branchless implemen-tation | 34 | | ------------- | ----------------------- | --------------------------- | ----------------------- | ---------------------------- | ------------------- | ------------- | ---------------------------- | -------------------------- | 35 | | CRC++ | 1 | Yes | Yes | Yes | Yes | Yes | Yes | Yes | 36 | | boost | 17 | Yes | Yes | Yes | Yes | Yes | No | No | 37 | | pycrc | 2 per CRC algorithm | No | No | No | No | No | No | No | 38 | | mhash | 6 | No | Yes | No | No | No | No | No | 39 | 40 | ### Usage 41 | 42 | Computing a CRC is as simple as the following code: 43 | 44 | ```cpp 45 | #include "CRC.h" // Only need to include this header file! 46 | // No libraries need to be included. No project settings need to be messed with. 47 | 48 | #include // Includes ::std::hex 49 | #include // Includes ::std::cout 50 | #include // Includes ::std::uint32_t 51 | 52 | int main(int argc, char ** argv) 53 | { 54 | const char myString[] = { 'H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D' }; 55 | 56 | std::uint32_t crc = CRC::Calculate(myString, sizeof(myString), CRC::CRC_32()); 57 | 58 | std::cout << std::hex << crc; 59 | 60 | return 0; 61 | } 62 | ``` 63 | 64 | Multi-part CRCs are also supported: 65 | 66 | ```cpp 67 | int main(int argc, char ** argv) 68 | { 69 | const char myHelloString[] = { 'H', 'E', 'L', 'L', 'O', ' ' }; 70 | const char myWorldString[] = { 'W', 'O', 'R', 'L', 'D' }; 71 | 72 | std::uint32_t crc; 73 | 74 | crc = CRC::Calculate(myHelloString, sizeof(myHelloString), CRC::CRC_32()); 75 | crc = CRC::Calculate(myWorldString, sizeof(myWorldString), CRC::CRC_32(), crc); 76 | 77 | std::cout << std::hex << crc; 78 | 79 | return 0; 80 | } 81 | ``` 82 | 83 | This will return the same CRC as the first example. 84 | 85 | If you need to compute a CRC on an input that is not a multiple of `CHAR_BIT` (usually 8 bits), use the `CalculateBits()` function instead: 86 | 87 | ```cpp 88 | int main(int argc, char ** argv) 89 | { 90 | const unsigned char data[] = { 0x98, 0x76, 0x54, 0x32, 0x10 }; 91 | 92 | // Second argument is the number of bits. The input data must 93 | // be a whole number of bytes. Pad any used bits with zeros. 94 | std::uint32_t crc = CRC::CalculateBits(data, 37, CRC::CRC_32()); 95 | 96 | std::cout << std::hex << crc; 97 | 98 | return 0; 99 | } 100 | ``` 101 | 102 | The above examples compute a CRC bit-by-bit. However, CRC++ also supports lookup tables, as the following example demonstrates: 103 | 104 | ```cpp 105 | int main(int argc, char ** argv) 106 | { 107 | const char myHelloString[] = { 'H', 'E', 'L', 'L', 'O', ' ' }; 108 | const char myWorldString[] = { 'W', 'O', 'R', 'L', 'D' }; 109 | 110 | CRC::Table table(CRC::CRC_32()); 111 | 112 | std::uint32_t crc; 113 | 114 | crc = CRC::Calculate(myHelloString, sizeof(myHelloString), table); 115 | crc = CRC::Calculate(myWorldString, sizeof(myWorldString), table, crc); 116 | 117 | std::cout << std::hex << crc; 118 | 119 | return 0; 120 | } 121 | ``` 122 | 123 | Or, if you prefer using the `auto` keyword: 124 | 125 | ```cpp 126 | int main(int argc, char ** argv) 127 | { 128 | const char myHelloString[] = { 'H', 'E', 'L', 'L', 'O', ' ' }; 129 | const char myWorldString[] = { 'W', 'O', 'R', 'L', 'D' }; 130 | 131 | auto table = CRC::CRC_32().MakeTable(); 132 | 133 | std::uint32_t crc; 134 | 135 | crc = CRC::Calculate(myHelloString, sizeof(myHelloString), table); 136 | crc = CRC::Calculate(myWorldString, sizeof(myWorldString), table, crc); 137 | 138 | std::cout << std::hex << crc; 139 | 140 | return 0; 141 | } 142 | ``` 143 | 144 | Lookup tables are much faster than computing a CRC bit-by-bit, at the expense of extra memory usage. A lookup table can be reused for as many CRCs as desired until it goes out of scope. 145 | 146 | ### Configuration 147 | 148 | CRC++ can be configured by setting various `#define`s before `#include`-ing the CRC++ header file: 149 | 150 | * `#define crcpp_uint8`
151 | Specifies the type used to store CRCs that have a width of 8 bits or less. This type is not used in CRC calculations. Defaults to ::std::uint8_t. 152 | * `#define crcpp_uint16`
153 | Specifies the type used to store CRCs that have a width between 9 and 16 bits (inclusive). This type is not used in CRC calculations. Defaults to ::std::uint16_t. 154 | * `#define crcpp_uint32`
155 | Specifies the type used to store CRCs that have a width between 17 and 32 bits (inclusive). This type is not used in CRC calculations. Defaults to ::std::uint32_t. 156 | * `#define crcpp_uint64`
157 | Specifies the type used to store CRCs that have a width between 33 and 64 bits (inclusive). This type is not used in CRC calculations. Defaults to ::std::uint64_t. 158 | * `#define crcpp_size`
159 | This type is used for loop iteration and function signatures only. Defaults to ::std::size_t. 160 | * `#define CRCPP_USE_NAMESPACE`
161 | Define to place all CRC++ code within the ::CRCPP namespace. Not defined by default. 162 | * `#define CRCPP_BRANCHLESS`
163 | Define to enable a branchless CRC implementation. The branchless implementation uses a single integer multiplication in the bit-by-bit calculation instead of a small conditional. The branchless implementation may be faster on processor architectures which support single-instruction integer multiplication. Not defined by default. 164 | * `#define CRCPP_USE_CPP11` 165 | Define to enables C++11 features (move semantics, constexpr, static_assert, etc.). Not defined by default. 166 | * `#define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS` 167 | Define to include definitions for little-used CRCs. Not defined by default. 168 | 169 | ### Documentation 170 | 171 | https://d-bahr.github.io/CRCpp/ 172 | 173 | ### License 174 | 175 | CRC++ is free to use and provided under a BSD license. 176 | 177 | ### References 178 | 179 | Catalog of CRCs: https://reveng.sourceforge.io/crc-catalogue/ 180 | 181 | 5G-NR Specification 3GPP TS 38.212: https://www.etsi.org/deliver/etsi_ts/138200_138299/138212/15.03.00_60/ts_138212v150300p.pdf 182 | 183 | USB 2.0 Specification: https://www.usb.org/document-library/usb-20-specification 184 | -------------------------------------------------------------------------------- /CRCx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef HT_UTIL_CRC_WRAPPER_H 4 | #define HT_UTIL_CRC_WRAPPER_H 5 | 6 | #ifdef ARDUINO 7 | #include 8 | #include 9 | #else 10 | #define CRCPP_USE_CPP11 11 | #define CRCPP_USE_NAMESPACE 12 | #define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 13 | #include "libs/CRCpp/CRC.h" 14 | #endif 15 | 16 | namespace ht { 17 | namespace util { 18 | namespace crc { 19 | 20 | enum class Crc8 : uint8_t { 21 | SMBUS, 22 | MAXIM 23 | }; 24 | 25 | enum class Crc16 : uint8_t { 26 | CCITT, 27 | KERMIT, 28 | MODBUS, 29 | XMODEM, 30 | X25 31 | }; 32 | 33 | enum class Crc32 : uint8_t { 34 | CRC32, 35 | POSIX 36 | }; 37 | 38 | #ifdef ARDUINO 39 | 40 | namespace fastcrc { 41 | inline uint8_t crc8(const uint8_t* data, const size_t size, const Crc8 type = Crc8::SMBUS) { 42 | static FastCRC8 fastcrc; 43 | switch (type) { 44 | case Crc8::SMBUS: return fastcrc.smbus(data, size); 45 | case Crc8::MAXIM: return fastcrc.maxim(data, size); 46 | } 47 | return 0xFF; 48 | } 49 | 50 | inline uint16_t crc16(const uint8_t* data, const size_t size, const Crc16 type = Crc16::MODBUS) { 51 | static FastCRC16 fastcrc; 52 | switch (type) { 53 | case Crc16::CCITT: return fastcrc.ccitt(data, size); 54 | case Crc16::KERMIT: return fastcrc.kermit(data, size); 55 | case Crc16::MODBUS: return fastcrc.modbus(data, size); 56 | case Crc16::XMODEM: return fastcrc.xmodem(data, size); 57 | case Crc16::X25: return fastcrc.x25(data, size); 58 | } 59 | return 0xFFFF; 60 | } 61 | 62 | inline uint32_t crc32(const uint8_t* data, const size_t size, const Crc32 type = Crc32::CRC32) { 63 | static FastCRC32 fastcrc; 64 | switch (type) { 65 | case Crc32::CRC32: return fastcrc.crc32(data, size); 66 | case Crc32::POSIX: return fastcrc.cksum(data, size); 67 | } 68 | return 0xFFFFFFFF; 69 | } 70 | 71 | inline uint8_t crc8_update(const uint8_t* data, const size_t size, const Crc8 type = Crc8::SMBUS) { 72 | static FastCRC8 fastcrc; 73 | static bool has_initialized {false}; 74 | if (!has_initialized) { 75 | has_initialized = true; 76 | switch (type) { 77 | case Crc8::SMBUS: return fastcrc.smbus(data, size); 78 | case Crc8::MAXIM: return fastcrc.maxim(data, size); 79 | } 80 | } else { 81 | switch (type) { 82 | case Crc8::SMBUS: return fastcrc.smbus_upd(data, size); 83 | case Crc8::MAXIM: return fastcrc.maxim_upd(data, size); 84 | } 85 | } 86 | return 0xFF; 87 | } 88 | 89 | inline uint16_t crc16_update(const uint8_t* data, const size_t size, const Crc16 type = Crc16::MODBUS) { 90 | static FastCRC16 fastcrc; 91 | static bool has_initialized {false}; 92 | if (!has_initialized) { 93 | has_initialized = true; 94 | switch (type) { 95 | case Crc16::CCITT: return fastcrc.ccitt(data, size); 96 | case Crc16::KERMIT: return fastcrc.kermit(data, size); 97 | case Crc16::MODBUS: return fastcrc.modbus(data, size); 98 | case Crc16::XMODEM: return fastcrc.xmodem(data, size); 99 | case Crc16::X25: return fastcrc.x25(data, size); 100 | } 101 | } else { 102 | switch (type) { 103 | case Crc16::CCITT: return fastcrc.ccitt_upd(data, size); 104 | case Crc16::KERMIT: return fastcrc.kermit_upd(data, size); 105 | case Crc16::MODBUS: return fastcrc.modbus_upd(data, size); 106 | case Crc16::XMODEM: return fastcrc.xmodem_upd(data, size); 107 | case Crc16::X25: return fastcrc.x25_upd(data, size); 108 | } 109 | } 110 | return 0xFFFF; 111 | } 112 | 113 | inline uint32_t crc32_update(const uint8_t* data, const size_t size, const Crc32 type = Crc32::CRC32) { 114 | static FastCRC32 fastcrc; 115 | static bool has_initialized {false}; 116 | if (!has_initialized) { 117 | has_initialized = true; 118 | switch (type) { 119 | case Crc32::CRC32: return fastcrc.crc32(data, size); 120 | case Crc32::POSIX: return fastcrc.cksum(data, size); 121 | } 122 | } else { 123 | switch (type) { 124 | case Crc32::CRC32: return fastcrc.crc32_upd(data, size); 125 | case Crc32::POSIX: return fastcrc.cksum_upd(data, size); 126 | } 127 | } 128 | return 0xFFFFFFFF; 129 | } 130 | 131 | } // namespace fastcrc 132 | 133 | using namespace fastcrc; 134 | #else 135 | 136 | namespace crcpp { 137 | using crc8_t = CRCPP::CRC::Parameters; 138 | using crc16_t = CRCPP::CRC::Parameters; 139 | using crc32_t = CRCPP::CRC::Parameters; 140 | using crc64_t = CRCPP::CRC::Parameters; 141 | 142 | inline crc8_t get_crc8_param(const Crc8 type) { 143 | switch (type) { 144 | case Crc8::SMBUS: return std::move(CRCPP::CRC::CRC_8()); 145 | case Crc8::MAXIM: return std::move(CRCPP::CRC::CRC_8_MAXIM()); 146 | } 147 | return std::move(CRCPP::CRC::CRC_8()); 148 | } 149 | 150 | inline crc16_t get_crc16_param(const Crc16 type) { 151 | switch (type) { 152 | case Crc16::CCITT: return std::move(CRCPP::CRC::CRC_16_CCITTFALSE()); 153 | case Crc16::KERMIT: return std::move(CRCPP::CRC::CRC_16_KERMIT()); 154 | case Crc16::MODBUS: return std::move(CRCPP::CRC::CRC_16_MODBUS()); 155 | case Crc16::XMODEM: return std::move(CRCPP::CRC::CRC_16_XMODEM()); 156 | case Crc16::X25: return std::move(CRCPP::CRC::CRC_16_X25()); 157 | } 158 | return std::move(CRCPP::CRC::CRC_16_MODBUS()); 159 | } 160 | 161 | inline crc32_t get_crc32_param(const Crc32 type) { 162 | switch (type) { 163 | case Crc32::CRC32: return std::move(CRCPP::CRC::CRC_32()); 164 | case Crc32::POSIX: return std::move(CRCPP::CRC::CRC_32_POSIX()); 165 | } 166 | return std::move(CRCPP::CRC::CRC_32()); 167 | } 168 | 169 | inline uint8_t crc8(const uint8_t* data, const size_t size, const Crc8 type = Crc8::SMBUS) { 170 | auto param = get_crc8_param(type); 171 | return CRCPP::CRC::Calculate(data, size, param); 172 | } 173 | 174 | inline uint16_t crc16(const uint8_t* data, const size_t size, const Crc16 type = Crc16::MODBUS) { 175 | auto param = get_crc16_param(type); 176 | return CRCPP::CRC::Calculate(data, size, param); 177 | } 178 | 179 | inline uint32_t crc32(const uint8_t* data, const size_t size, const Crc32 type = Crc32::CRC32) { 180 | auto param = get_crc32_param(type); 181 | return CRCPP::CRC::Calculate(data, size, param); 182 | } 183 | 184 | inline uint64_t crc64(const uint8_t* data, const size_t size) { 185 | return CRCPP::CRC::Calculate(data, size, CRCPP::CRC::CRC_64()); 186 | } 187 | 188 | inline uint8_t crc8_update(const uint8_t* data, const size_t size, const Crc8 type = Crc8::SMBUS) { 189 | static auto param = get_crc8_param(type); 190 | static bool has_initialized {false}; 191 | static uint8_t result {0}; 192 | if (!has_initialized) { 193 | has_initialized = true; 194 | result = CRCPP::CRC::Calculate(data, size, param); 195 | } else { 196 | result = CRCPP::CRC::Calculate(data, size, param, result); 197 | } 198 | return result; 199 | } 200 | 201 | inline uint16_t crc16_update(const uint8_t* data, const size_t size, const Crc16 type = Crc16::MODBUS) { 202 | static auto param = get_crc16_param(type); 203 | static bool has_initialized {false}; 204 | static uint16_t result {0}; 205 | if (!has_initialized) { 206 | has_initialized = true; 207 | result = CRCPP::CRC::Calculate(data, size, param); 208 | } else { 209 | result = CRCPP::CRC::Calculate(data, size, param, result); 210 | } 211 | return result; 212 | } 213 | 214 | inline uint32_t crc32_update(const uint8_t* data, const size_t size, const Crc32 type = Crc32::CRC32) { 215 | static auto param = get_crc32_param(type); 216 | static bool has_initialized {false}; 217 | static uint32_t result {0}; 218 | if (!has_initialized) { 219 | has_initialized = true; 220 | result = CRCPP::CRC::Calculate(data, size, param); 221 | } else { 222 | result = CRCPP::CRC::Calculate(data, size, param, result); 223 | } 224 | return result; 225 | } 226 | 227 | inline uint64_t crc64_update(const uint8_t* data, const size_t size) { 228 | static auto param = CRCPP::CRC::CRC_64(); 229 | static bool has_initialized {false}; 230 | static uint64_t result {0}; 231 | if (!has_initialized) { 232 | has_initialized = true; 233 | result = CRCPP::CRC::Calculate(data, size, param); 234 | } else { 235 | result = CRCPP::CRC::Calculate(data, size, param, result); 236 | } 237 | return result; 238 | } 239 | } // namespace crcpp 240 | 241 | using namespace crcpp; 242 | #endif 243 | 244 | } // namespace crc 245 | } // namespace util 246 | } // namespace ht 247 | 248 | namespace crcx = ht::util::crc; 249 | 250 | #endif // HT_UTIL_CRC_WRAPPER_H 251 | -------------------------------------------------------------------------------- /libs/CRCpp/CRC.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file CRC.h 3 | @author Daniel Bahr 4 | @version 1.1.0.0 5 | @copyright 6 | @parblock 7 | CRC++ 8 | Copyright (c) 2021, Daniel Bahr 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright notice, this 15 | list of conditions and the following disclaimer. 16 | 17 | * Redistributions in binary form must reproduce the above copyright notice, 18 | this list of conditions and the following disclaimer in the documentation 19 | and/or other materials provided with the distribution. 20 | 21 | * Neither the name of CRC++ nor the names of its 22 | contributors may be used to endorse or promote products derived from 23 | this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 29 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | @endparblock 36 | */ 37 | 38 | /* 39 | CRC++ can be configured by setting various #defines before #including this header file: 40 | 41 | #define crcpp_uint8 - Specifies the type used to store CRCs that have a width of 8 bits or less. 42 | This type is not used in CRC calculations. Defaults to ::std::uint8_t. 43 | #define crcpp_uint16 - Specifies the type used to store CRCs that have a width between 9 and 16 bits (inclusive). 44 | This type is not used in CRC calculations. Defaults to ::std::uint16_t. 45 | #define crcpp_uint32 - Specifies the type used to store CRCs that have a width between 17 and 32 bits (inclusive). 46 | This type is not used in CRC calculations. Defaults to ::std::uint32_t. 47 | #define crcpp_uint64 - Specifies the type used to store CRCs that have a width between 33 and 64 bits (inclusive). 48 | This type is not used in CRC calculations. Defaults to ::std::uint64_t. 49 | #define crcpp_size - This type is used for loop iteration and function signatures only. Defaults to ::std::size_t. 50 | #define CRCPP_USE_NAMESPACE - Define to place all CRC++ code within the ::CRCPP namespace. 51 | #define CRCPP_BRANCHLESS - Define to enable a branchless CRC implementation. The branchless implementation uses a single integer 52 | multiplication in the bit-by-bit calculation instead of a small conditional. The branchless implementation 53 | may be faster on processor architectures which support single-instruction integer multiplication. 54 | #define CRCPP_USE_CPP11 - Define to enables C++11 features (move semantics, constexpr, static_assert, etc.). 55 | #define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - Define to include definitions for little-used CRCs. 56 | */ 57 | 58 | #ifndef CRCPP_CRC_H_ 59 | #define CRCPP_CRC_H_ 60 | 61 | #include // Includes CHAR_BIT 62 | #ifdef CRCPP_USE_CPP11 63 | #include // Includes ::std::size_t 64 | #include // Includes ::std::uint8_t, ::std::uint16_t, ::std::uint32_t, ::std::uint64_t 65 | #else 66 | #include // Includes size_t 67 | #include // Includes uint8_t, uint16_t, uint32_t, uint64_t 68 | #endif 69 | #include // Includes ::std::numeric_limits 70 | #include // Includes ::std::move 71 | 72 | #ifndef crcpp_uint8 73 | # ifdef CRCPP_USE_CPP11 74 | /// @brief Unsigned 8-bit integer definition, used primarily for parameter definitions. 75 | # define crcpp_uint8 ::std::uint8_t 76 | # else 77 | /// @brief Unsigned 8-bit integer definition, used primarily for parameter definitions. 78 | # define crcpp_uint8 uint8_t 79 | # endif 80 | #endif 81 | 82 | #ifndef crcpp_uint16 83 | # ifdef CRCPP_USE_CPP11 84 | /// @brief Unsigned 16-bit integer definition, used primarily for parameter definitions. 85 | # define crcpp_uint16 ::std::uint16_t 86 | # else 87 | /// @brief Unsigned 16-bit integer definition, used primarily for parameter definitions. 88 | # define crcpp_uint16 uint16_t 89 | # endif 90 | #endif 91 | 92 | #ifndef crcpp_uint32 93 | # ifdef CRCPP_USE_CPP11 94 | /// @brief Unsigned 32-bit integer definition, used primarily for parameter definitions. 95 | # define crcpp_uint32 ::std::uint32_t 96 | # else 97 | /// @brief Unsigned 32-bit integer definition, used primarily for parameter definitions. 98 | # define crcpp_uint32 uint32_t 99 | # endif 100 | #endif 101 | 102 | #ifndef crcpp_uint64 103 | # ifdef CRCPP_USE_CPP11 104 | /// @brief Unsigned 64-bit integer definition, used primarily for parameter definitions. 105 | # define crcpp_uint64 ::std::uint64_t 106 | # else 107 | /// @brief Unsigned 64-bit integer definition, used primarily for parameter definitions. 108 | # define crcpp_uint64 uint64_t 109 | # endif 110 | #endif 111 | 112 | #ifndef crcpp_size 113 | # ifdef CRCPP_USE_CPP11 114 | /// @brief Unsigned size definition, used for specifying data sizes. 115 | # define crcpp_size ::std::size_t 116 | # else 117 | /// @brief Unsigned size definition, used for specifying data sizes. 118 | # define crcpp_size size_t 119 | # endif 120 | #endif 121 | 122 | #ifdef CRCPP_USE_CPP11 123 | /// @brief Compile-time expression definition. 124 | # define crcpp_constexpr constexpr 125 | #else 126 | /// @brief Compile-time expression definition. 127 | # define crcpp_constexpr const 128 | #endif 129 | 130 | #ifdef CRCPP_USE_NAMESPACE 131 | namespace CRCPP 132 | { 133 | #endif 134 | 135 | /** 136 | @brief Static class for computing CRCs. 137 | @note This class supports computation of full and multi-part CRCs, using a bit-by-bit algorithm or a 138 | byte-by-byte lookup table. The CRCs are calculated using as many optimizations as is reasonable. 139 | If compiling with C++11, the constexpr keyword is used liberally so that many calculations are 140 | performed at compile-time instead of at runtime. 141 | */ 142 | class CRC 143 | { 144 | public: 145 | // Forward declaration 146 | template 147 | struct Table; 148 | 149 | /** 150 | @brief CRC parameters. 151 | */ 152 | template 153 | struct Parameters 154 | { 155 | CRCType polynomial; ///< CRC polynomial 156 | CRCType initialValue; ///< Initial CRC value 157 | CRCType finalXOR; ///< Value to XOR with the final CRC 158 | bool reflectInput; ///< true to reflect all input bytes 159 | bool reflectOutput; ///< true to reflect the output CRC (reflection occurs before the final XOR) 160 | 161 | Table MakeTable() const; 162 | }; 163 | 164 | /** 165 | @brief CRC lookup table. After construction, the CRC parameters are fixed. 166 | @note A CRC table can be used for multiple CRC calculations. 167 | */ 168 | template 169 | struct Table 170 | { 171 | // Constructors are intentionally NOT marked explicit. 172 | Table(const Parameters & parameters); 173 | 174 | #ifdef CRCPP_USE_CPP11 175 | Table(Parameters && parameters); 176 | #endif 177 | 178 | const Parameters & GetParameters() const; 179 | 180 | const CRCType * GetTable() const; 181 | 182 | CRCType operator[](unsigned char index) const; 183 | 184 | private: 185 | void InitTable(); 186 | 187 | Parameters parameters; ///< CRC parameters used to construct the table 188 | CRCType table[1 << CHAR_BIT]; ///< CRC lookup table 189 | }; 190 | 191 | // The number of bits in CRCType must be at least as large as CRCWidth. 192 | // CRCType must be an unsigned integer type or a custom type with operator overloads. 193 | template 194 | static CRCType Calculate(const void * data, crcpp_size size, const Parameters & parameters); 195 | 196 | template 197 | static CRCType Calculate(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc); 198 | 199 | template 200 | static CRCType Calculate(const void * data, crcpp_size size, const Table & lookupTable); 201 | 202 | template 203 | static CRCType Calculate(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc); 204 | 205 | template 206 | static CRCType CalculateBits(const void * data, crcpp_size size, const Parameters & parameters); 207 | 208 | template 209 | static CRCType CalculateBits(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc); 210 | 211 | template 212 | static CRCType CalculateBits(const void * data, crcpp_size size, const Table & lookupTable); 213 | 214 | template 215 | static CRCType CalculateBits(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc); 216 | 217 | // Common CRCs up to 64 bits. 218 | // Note: Check values are the computed CRCs when given an ASCII input of "123456789" (without null terminator) 219 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 220 | static const Parameters< crcpp_uint8, 4> & CRC_4_ITU(); 221 | static const Parameters< crcpp_uint8, 5> & CRC_5_EPC(); 222 | static const Parameters< crcpp_uint8, 5> & CRC_5_ITU(); 223 | static const Parameters< crcpp_uint8, 5> & CRC_5_USB(); 224 | static const Parameters< crcpp_uint8, 6> & CRC_6_CDMA2000A(); 225 | static const Parameters< crcpp_uint8, 6> & CRC_6_CDMA2000B(); 226 | static const Parameters< crcpp_uint8, 6> & CRC_6_ITU(); 227 | static const Parameters< crcpp_uint8, 6> & CRC_6_NR(); 228 | static const Parameters< crcpp_uint8, 7> & CRC_7(); 229 | #endif 230 | static const Parameters< crcpp_uint8, 8> & CRC_8(); 231 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 232 | static const Parameters< crcpp_uint8, 8> & CRC_8_EBU(); 233 | static const Parameters< crcpp_uint8, 8> & CRC_8_MAXIM(); 234 | static const Parameters< crcpp_uint8, 8> & CRC_8_WCDMA(); 235 | static const Parameters< crcpp_uint8, 8> & CRC_8_LTE(); 236 | static const Parameters & CRC_10(); 237 | static const Parameters & CRC_10_CDMA2000(); 238 | static const Parameters & CRC_11(); 239 | static const Parameters & CRC_11_NR(); 240 | static const Parameters & CRC_12_CDMA2000(); 241 | static const Parameters & CRC_12_DECT(); 242 | static const Parameters & CRC_12_UMTS(); 243 | static const Parameters & CRC_13_BBC(); 244 | static const Parameters & CRC_15(); 245 | static const Parameters & CRC_15_MPT1327(); 246 | #endif 247 | static const Parameters & CRC_16_ARC(); 248 | static const Parameters & CRC_16_BUYPASS(); 249 | static const Parameters & CRC_16_CCITTFALSE(); 250 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 251 | static const Parameters & CRC_16_CDMA2000(); 252 | static const Parameters & CRC_16_CMS(); 253 | static const Parameters & CRC_16_DECTR(); 254 | static const Parameters & CRC_16_DECTX(); 255 | static const Parameters & CRC_16_DNP(); 256 | #endif 257 | static const Parameters & CRC_16_GENIBUS(); 258 | static const Parameters & CRC_16_KERMIT(); 259 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 260 | static const Parameters & CRC_16_MAXIM(); 261 | static const Parameters & CRC_16_MODBUS(); 262 | static const Parameters & CRC_16_T10DIF(); 263 | static const Parameters & CRC_16_USB(); 264 | #endif 265 | static const Parameters & CRC_16_X25(); 266 | static const Parameters & CRC_16_XMODEM(); 267 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 268 | static const Parameters & CRC_17_CAN(); 269 | static const Parameters & CRC_21_CAN(); 270 | static const Parameters & CRC_24(); 271 | static const Parameters & CRC_24_FLEXRAYA(); 272 | static const Parameters & CRC_24_FLEXRAYB(); 273 | static const Parameters & CRC_24_LTEA(); 274 | static const Parameters & CRC_24_LTEB(); 275 | static const Parameters & CRC_24_NRC(); 276 | static const Parameters & CRC_30(); 277 | #endif 278 | static const Parameters & CRC_32(); 279 | static const Parameters & CRC_32_BZIP2(); 280 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 281 | static const Parameters & CRC_32_C(); 282 | #endif 283 | static const Parameters & CRC_32_MPEG2(); 284 | static const Parameters & CRC_32_POSIX(); 285 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 286 | static const Parameters & CRC_32_Q(); 287 | static const Parameters & CRC_40_GSM(); 288 | static const Parameters & CRC_64(); 289 | #endif 290 | 291 | #ifdef CRCPP_USE_CPP11 292 | CRC() = delete; 293 | CRC(const CRC & other) = delete; 294 | CRC & operator=(const CRC & other) = delete; 295 | CRC(CRC && other) = delete; 296 | CRC & operator=(CRC && other) = delete; 297 | #endif 298 | 299 | private: 300 | #ifndef CRCPP_USE_CPP11 301 | CRC(); 302 | CRC(const CRC & other); 303 | CRC & operator=(const CRC & other); 304 | #endif 305 | 306 | template 307 | static IntegerType Reflect(IntegerType value, crcpp_uint16 numBits); 308 | 309 | template 310 | static CRCType Finalize(CRCType remainder, CRCType finalXOR, bool reflectOutput); 311 | 312 | template 313 | static CRCType UndoFinalize(CRCType remainder, CRCType finalXOR, bool reflectOutput); 314 | 315 | template 316 | static CRCType CalculateRemainder(const void * data, crcpp_size size, const Parameters & parameters, CRCType remainder); 317 | 318 | template 319 | static CRCType CalculateRemainder(const void * data, crcpp_size size, const Table & lookupTable, CRCType remainder); 320 | 321 | template 322 | static CRCType CalculateRemainderBits(unsigned char byte, crcpp_size numBits, const Parameters & parameters, CRCType remainder); 323 | }; 324 | 325 | /** 326 | @brief Returns a CRC lookup table construct using these CRC parameters. 327 | @note This function primarily exists to allow use of the auto keyword instead of instantiating 328 | a table directly, since template parameters are not inferred in constructors. 329 | @tparam CRCType Integer type for storing the CRC result 330 | @tparam CRCWidth Number of bits in the CRC 331 | @return CRC lookup table 332 | */ 333 | template 334 | inline CRC::Table CRC::Parameters::MakeTable() const 335 | { 336 | // This should take advantage of RVO and optimize out the copy. 337 | return CRC::Table(*this); 338 | } 339 | 340 | /** 341 | @brief Constructs a CRC table from a set of CRC parameters 342 | @param[in] params CRC parameters 343 | @tparam CRCType Integer type for storing the CRC result 344 | @tparam CRCWidth Number of bits in the CRC 345 | */ 346 | template 347 | inline CRC::Table::Table(const Parameters & params) : 348 | parameters(params) 349 | { 350 | InitTable(); 351 | } 352 | 353 | #ifdef CRCPP_USE_CPP11 354 | /** 355 | @brief Constructs a CRC table from a set of CRC parameters 356 | @param[in] params CRC parameters 357 | @tparam CRCType Integer type for storing the CRC result 358 | @tparam CRCWidth Number of bits in the CRC 359 | */ 360 | template 361 | inline CRC::Table::Table(Parameters && params) : 362 | parameters(::std::move(params)) 363 | { 364 | InitTable(); 365 | } 366 | #endif 367 | 368 | /** 369 | @brief Gets the CRC parameters used to construct the CRC table 370 | @tparam CRCType Integer type for storing the CRC result 371 | @tparam CRCWidth Number of bits in the CRC 372 | @return CRC parameters 373 | */ 374 | template 375 | inline const CRC::Parameters & CRC::Table::GetParameters() const 376 | { 377 | return parameters; 378 | } 379 | 380 | /** 381 | @brief Gets the CRC table 382 | @tparam CRCType Integer type for storing the CRC result 383 | @tparam CRCWidth Number of bits in the CRC 384 | @return CRC table 385 | */ 386 | template 387 | inline const CRCType * CRC::Table::GetTable() const 388 | { 389 | return table; 390 | } 391 | 392 | /** 393 | @brief Gets an entry in the CRC table 394 | @param[in] index Index into the CRC table 395 | @tparam CRCType Integer type for storing the CRC result 396 | @tparam CRCWidth Number of bits in the CRC 397 | @return CRC table entry 398 | */ 399 | template 400 | inline CRCType CRC::Table::operator[](unsigned char index) const 401 | { 402 | return table[index]; 403 | } 404 | 405 | /** 406 | @brief Initializes a CRC table. 407 | @tparam CRCType Integer type for storing the CRC result 408 | @tparam CRCWidth Number of bits in the CRC 409 | */ 410 | template 411 | inline void CRC::Table::InitTable() 412 | { 413 | // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) 414 | static crcpp_constexpr CRCType BIT_MASK((CRCType(1) << (CRCWidth - CRCType(1))) | 415 | ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1))); 416 | 417 | // The conditional expression is used to avoid a -Wshift-count-overflow warning. 418 | static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); 419 | 420 | CRCType crc; 421 | unsigned char byte = 0; 422 | 423 | // Loop over each dividend (each possible number storable in an unsigned char) 424 | do 425 | { 426 | crc = CRC::CalculateRemainder(&byte, sizeof(byte), parameters, CRCType(0)); 427 | 428 | // This mask might not be necessary; all unit tests pass with this line commented out, 429 | // but that might just be a coincidence based on the CRC parameters used for testing. 430 | // In any case, this is harmless to leave in and only adds a single machine instruction per loop iteration. 431 | crc &= BIT_MASK; 432 | 433 | if (!parameters.reflectInput && CRCWidth < CHAR_BIT) 434 | { 435 | // Undo the special operation at the end of the CalculateRemainder() 436 | // function for non-reflected CRCs < CHAR_BIT. 437 | crc = static_cast(crc << SHIFT); 438 | } 439 | 440 | table[byte] = crc; 441 | } 442 | while (++byte); 443 | } 444 | 445 | /** 446 | @brief Computes a CRC. 447 | @param[in] data Data over which CRC will be computed 448 | @param[in] size Size of the data, in bytes 449 | @param[in] parameters CRC parameters 450 | @tparam CRCType Integer type for storing the CRC result 451 | @tparam CRCWidth Number of bits in the CRC 452 | @return CRC 453 | */ 454 | template 455 | inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Parameters & parameters) 456 | { 457 | CRCType remainder = CalculateRemainder(data, size, parameters, parameters.initialValue); 458 | 459 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 460 | 461 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 462 | } 463 | /** 464 | @brief Appends additional data to a previous CRC calculation. 465 | @note This function can be used to compute multi-part CRCs. 466 | @param[in] data Data over which CRC will be computed 467 | @param[in] size Size of the data, in bytes 468 | @param[in] parameters CRC parameters 469 | @param[in] crc CRC from a previous calculation 470 | @tparam CRCType Integer type for storing the CRC result 471 | @tparam CRCWidth Number of bits in the CRC 472 | @return CRC 473 | */ 474 | template 475 | inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc) 476 | { 477 | CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 478 | 479 | remainder = CalculateRemainder(data, size, parameters, remainder); 480 | 481 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 482 | 483 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 484 | } 485 | 486 | /** 487 | @brief Computes a CRC via a lookup table. 488 | @param[in] data Data over which CRC will be computed 489 | @param[in] size Size of the data, in bytes 490 | @param[in] lookupTable CRC lookup table 491 | @tparam CRCType Integer type for storing the CRC result 492 | @tparam CRCWidth Number of bits in the CRC 493 | @return CRC 494 | */ 495 | template 496 | inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Table & lookupTable) 497 | { 498 | const Parameters & parameters = lookupTable.GetParameters(); 499 | 500 | CRCType remainder = CalculateRemainder(data, size, lookupTable, parameters.initialValue); 501 | 502 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 503 | 504 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 505 | } 506 | 507 | /** 508 | @brief Appends additional data to a previous CRC calculation using a lookup table. 509 | @note This function can be used to compute multi-part CRCs. 510 | @param[in] data Data over which CRC will be computed 511 | @param[in] size Size of the data, in bytes 512 | @param[in] lookupTable CRC lookup table 513 | @param[in] crc CRC from a previous calculation 514 | @tparam CRCType Integer type for storing the CRC result 515 | @tparam CRCWidth Number of bits in the CRC 516 | @return CRC 517 | */ 518 | template 519 | inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc) 520 | { 521 | const Parameters & parameters = lookupTable.GetParameters(); 522 | 523 | CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 524 | 525 | remainder = CalculateRemainder(data, size, lookupTable, remainder); 526 | 527 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 528 | 529 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 530 | } 531 | 532 | /** 533 | @brief Computes a CRC. 534 | @param[in] data Data over which CRC will be computed 535 | @param[in] size Size of the data, in bits 536 | @param[in] parameters CRC parameters 537 | @tparam CRCType Integer type for storing the CRC result 538 | @tparam CRCWidth Number of bits in the CRC 539 | @return CRC 540 | */ 541 | template 542 | inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Parameters & parameters) 543 | { 544 | CRCType remainder = parameters.initialValue; 545 | 546 | // Calculate the remainder on a whole number of bytes first, then call 547 | // a special-case function for the remaining bits. 548 | crcpp_size wholeNumberOfBytes = size / CHAR_BIT; 549 | if (wholeNumberOfBytes > 0) 550 | { 551 | remainder = CalculateRemainder(data, wholeNumberOfBytes, parameters, remainder); 552 | } 553 | 554 | crcpp_size remainingNumberOfBits = size % CHAR_BIT; 555 | if (remainingNumberOfBits != 0) 556 | { 557 | unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); 558 | remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); 559 | } 560 | 561 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 562 | 563 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 564 | } 565 | /** 566 | @brief Appends additional data to a previous CRC calculation. 567 | @note This function can be used to compute multi-part CRCs. 568 | @param[in] data Data over which CRC will be computed 569 | @param[in] size Size of the data, in bits 570 | @param[in] parameters CRC parameters 571 | @param[in] crc CRC from a previous calculation 572 | @tparam CRCType Integer type for storing the CRC result 573 | @tparam CRCWidth Number of bits in the CRC 574 | @return CRC 575 | */ 576 | template 577 | inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc) 578 | { 579 | CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 580 | 581 | // Calculate the remainder on a whole number of bytes first, then call 582 | // a special-case function for the remaining bits. 583 | crcpp_size wholeNumberOfBytes = size / CHAR_BIT; 584 | if (wholeNumberOfBytes > 0) 585 | { 586 | remainder = CalculateRemainder(data, wholeNumberOfBytes, parameters, parameters.initialValue); 587 | } 588 | 589 | crcpp_size remainingNumberOfBits = size % CHAR_BIT; 590 | if (remainingNumberOfBits != 0) 591 | { 592 | unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); 593 | remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); 594 | } 595 | 596 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 597 | 598 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 599 | } 600 | 601 | /** 602 | @brief Computes a CRC via a lookup table. 603 | @param[in] data Data over which CRC will be computed 604 | @param[in] size Size of the data, in bits 605 | @param[in] lookupTable CRC lookup table 606 | @tparam CRCType Integer type for storing the CRC result 607 | @tparam CRCWidth Number of bits in the CRC 608 | @return CRC 609 | */ 610 | template 611 | inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Table & lookupTable) 612 | { 613 | const Parameters & parameters = lookupTable.GetParameters(); 614 | 615 | CRCType remainder = parameters.initialValue; 616 | 617 | // Calculate the remainder on a whole number of bytes first, then call 618 | // a special-case function for the remaining bits. 619 | crcpp_size wholeNumberOfBytes = size / CHAR_BIT; 620 | if (wholeNumberOfBytes > 0) 621 | { 622 | remainder = CalculateRemainder(data, wholeNumberOfBytes, lookupTable, remainder); 623 | } 624 | 625 | crcpp_size remainingNumberOfBits = size % CHAR_BIT; 626 | if (remainingNumberOfBits != 0) 627 | { 628 | unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); 629 | remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); 630 | } 631 | 632 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 633 | 634 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 635 | } 636 | 637 | /** 638 | @brief Appends additional data to a previous CRC calculation using a lookup table. 639 | @note This function can be used to compute multi-part CRCs. 640 | @param[in] data Data over which CRC will be computed 641 | @param[in] size Size of the data, in bits 642 | @param[in] lookupTable CRC lookup table 643 | @param[in] crc CRC from a previous calculation 644 | @tparam CRCType Integer type for storing the CRC result 645 | @tparam CRCWidth Number of bits in the CRC 646 | @return CRC 647 | */ 648 | template 649 | inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc) 650 | { 651 | const Parameters & parameters = lookupTable.GetParameters(); 652 | 653 | CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 654 | 655 | // Calculate the remainder on a whole number of bytes first, then call 656 | // a special-case function for the remaining bits. 657 | crcpp_size wholeNumberOfBytes = size / CHAR_BIT; 658 | if (wholeNumberOfBytes > 0) 659 | { 660 | remainder = CalculateRemainder(data, wholeNumberOfBytes, lookupTable, parameters.initialValue); 661 | } 662 | 663 | crcpp_size remainingNumberOfBits = size % CHAR_BIT; 664 | if (remainingNumberOfBits > 0) 665 | { 666 | unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); 667 | remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); 668 | } 669 | 670 | // No need to mask the remainder here; the mask will be applied in the Finalize() function. 671 | 672 | return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); 673 | } 674 | 675 | /** 676 | @brief Reflects (i.e. reverses the bits within) an integer value. 677 | @param[in] value Value to reflect 678 | @param[in] numBits Number of bits in the integer which will be reflected 679 | @tparam IntegerType Integer type of the value being reflected 680 | @return Reflected value 681 | */ 682 | template 683 | inline IntegerType CRC::Reflect(IntegerType value, crcpp_uint16 numBits) 684 | { 685 | IntegerType reversedValue(0); 686 | 687 | for (crcpp_uint16 i = 0; i < numBits; ++i) 688 | { 689 | reversedValue = static_cast((reversedValue << 1) | (value & 1)); 690 | value = static_cast(value >> 1); 691 | } 692 | 693 | return reversedValue; 694 | } 695 | 696 | /** 697 | @brief Computes the final reflection and XOR of a CRC remainder. 698 | @param[in] remainder CRC remainder to reflect and XOR 699 | @param[in] finalXOR Final value to XOR with the remainder 700 | @param[in] reflectOutput true to reflect each byte of the remainder before the XOR 701 | @tparam CRCType Integer type for storing the CRC result 702 | @tparam CRCWidth Number of bits in the CRC 703 | @return Final CRC 704 | */ 705 | template 706 | inline CRCType CRC::Finalize(CRCType remainder, CRCType finalXOR, bool reflectOutput) 707 | { 708 | // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) 709 | static crcpp_constexpr CRCType BIT_MASK = (CRCType(1) << (CRCWidth - CRCType(1))) | 710 | ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1)); 711 | 712 | if (reflectOutput) 713 | { 714 | remainder = Reflect(remainder, CRCWidth); 715 | } 716 | 717 | return (remainder ^ finalXOR) & BIT_MASK; 718 | } 719 | 720 | /** 721 | @brief Undoes the process of computing the final reflection and XOR of a CRC remainder. 722 | @note This function allows for computation of multi-part CRCs 723 | @note Calling UndoFinalize() followed by Finalize() (or vice versa) will always return the original remainder value: 724 | 725 | CRCType x = ...; 726 | CRCType y = Finalize(x, finalXOR, reflectOutput); 727 | CRCType z = UndoFinalize(y, finalXOR, reflectOutput); 728 | assert(x == z); 729 | 730 | @param[in] crc Reflected and XORed CRC 731 | @param[in] finalXOR Final value XORed with the remainder 732 | @param[in] reflectOutput true if the remainder is to be reflected 733 | @tparam CRCType Integer type for storing the CRC result 734 | @tparam CRCWidth Number of bits in the CRC 735 | @return Un-finalized CRC remainder 736 | */ 737 | template 738 | inline CRCType CRC::UndoFinalize(CRCType crc, CRCType finalXOR, bool reflectOutput) 739 | { 740 | // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) 741 | static crcpp_constexpr CRCType BIT_MASK = (CRCType(1) << (CRCWidth - CRCType(1))) | 742 | ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1)); 743 | 744 | crc = (crc & BIT_MASK) ^ finalXOR; 745 | 746 | if (reflectOutput) 747 | { 748 | crc = Reflect(crc, CRCWidth); 749 | } 750 | 751 | return crc; 752 | } 753 | 754 | /** 755 | @brief Computes a CRC remainder. 756 | @param[in] data Data over which the remainder will be computed 757 | @param[in] size Size of the data, in bytes 758 | @param[in] parameters CRC parameters 759 | @param[in] remainder Running CRC remainder. Can be an initial value or the result of a previous CRC remainder calculation. 760 | @tparam CRCType Integer type for storing the CRC result 761 | @tparam CRCWidth Number of bits in the CRC 762 | @return CRC remainder 763 | */ 764 | template 765 | inline CRCType CRC::CalculateRemainder(const void * data, crcpp_size size, const Parameters & parameters, CRCType remainder) 766 | { 767 | #ifdef CRCPP_USE_CPP11 768 | // This static_assert is put here because this function will always be compiled in no matter what 769 | // the template parameters are and whether or not a table lookup or bit-by-bit algorithm is used. 770 | static_assert(::std::numeric_limits::digits >= CRCWidth, "CRCType is too small to contain a CRC of width CRCWidth."); 771 | #else 772 | // Catching this compile-time error is very important. Sadly, the compiler error will be very cryptic, but it's 773 | // better than nothing. 774 | enum { static_assert_failed_CRCType_is_too_small_to_contain_a_CRC_of_width_CRCWidth = 1 / (::std::numeric_limits::digits >= CRCWidth ? 1 : 0) }; 775 | #endif 776 | 777 | const unsigned char * current = reinterpret_cast(data); 778 | 779 | // Slightly different implementations based on the parameters. The current implementations try to eliminate as much 780 | // computation from the inner loop (looping over each bit) as possible. 781 | if (parameters.reflectInput) 782 | { 783 | CRCType polynomial = CRC::Reflect(parameters.polynomial, CRCWidth); 784 | while (size--) 785 | { 786 | remainder = static_cast(remainder ^ *current++); 787 | 788 | // An optimizing compiler might choose to unroll this loop. 789 | for (crcpp_size i = 0; i < CHAR_BIT; ++i) 790 | { 791 | #ifdef CRCPP_BRANCHLESS 792 | // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: 793 | // if (remainder & 1) 794 | // remainder = (remainder >> 1) ^ polynomial; 795 | // else 796 | // remainder >>= 1; 797 | remainder = static_cast((remainder >> 1) ^ ((remainder & 1) * polynomial)); 798 | #else 799 | remainder = static_cast((remainder & 1) ? ((remainder >> 1) ^ polynomial) : (remainder >> 1)); 800 | #endif 801 | } 802 | } 803 | } 804 | else if (CRCWidth >= CHAR_BIT) 805 | { 806 | static crcpp_constexpr CRCType CRC_WIDTH_MINUS_ONE(CRCWidth - CRCType(1)); 807 | #ifndef CRCPP_BRANCHLESS 808 | static crcpp_constexpr CRCType CRC_HIGHEST_BIT_MASK(CRCType(1) << CRC_WIDTH_MINUS_ONE); 809 | #endif 810 | // The conditional expression is used to avoid a -Wshift-count-overflow warning. 811 | static crcpp_constexpr CRCType SHIFT((CRCWidth >= CHAR_BIT) ? static_cast(CRCWidth - CHAR_BIT) : 0); 812 | 813 | while (size--) 814 | { 815 | remainder = static_cast(remainder ^ (static_cast(*current++) << SHIFT)); 816 | 817 | // An optimizing compiler might choose to unroll this loop. 818 | for (crcpp_size i = 0; i < CHAR_BIT; ++i) 819 | { 820 | #ifdef CRCPP_BRANCHLESS 821 | // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: 822 | // if (remainder & CRC_HIGHEST_BIT_MASK) 823 | // remainder = (remainder << 1) ^ parameters.polynomial; 824 | // else 825 | // remainder <<= 1; 826 | remainder = static_cast((remainder << 1) ^ (((remainder >> CRC_WIDTH_MINUS_ONE) & 1) * parameters.polynomial)); 827 | #else 828 | remainder = static_cast((remainder & CRC_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ parameters.polynomial) : (remainder << 1)); 829 | #endif 830 | } 831 | } 832 | } 833 | else 834 | { 835 | static crcpp_constexpr CRCType CHAR_BIT_MINUS_ONE(CHAR_BIT - 1); 836 | #ifndef CRCPP_BRANCHLESS 837 | static crcpp_constexpr CRCType CHAR_BIT_HIGHEST_BIT_MASK(CRCType(1) << CHAR_BIT_MINUS_ONE); 838 | #endif 839 | // The conditional expression is used to avoid a -Wshift-count-overflow warning. 840 | static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); 841 | 842 | CRCType polynomial = static_cast(parameters.polynomial << SHIFT); 843 | remainder = static_cast(remainder << SHIFT); 844 | 845 | while (size--) 846 | { 847 | remainder = static_cast(remainder ^ *current++); 848 | 849 | // An optimizing compiler might choose to unroll this loop. 850 | for (crcpp_size i = 0; i < CHAR_BIT; ++i) 851 | { 852 | #ifdef CRCPP_BRANCHLESS 853 | // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: 854 | // if (remainder & CHAR_BIT_HIGHEST_BIT_MASK) 855 | // remainder = (remainder << 1) ^ polynomial; 856 | // else 857 | // remainder <<= 1; 858 | remainder = static_cast((remainder << 1) ^ (((remainder >> CHAR_BIT_MINUS_ONE) & 1) * polynomial)); 859 | #else 860 | remainder = static_cast((remainder & CHAR_BIT_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ polynomial) : (remainder << 1)); 861 | #endif 862 | } 863 | } 864 | 865 | remainder = static_cast(remainder >> SHIFT); 866 | } 867 | 868 | return remainder; 869 | } 870 | 871 | /** 872 | @brief Computes a CRC remainder using lookup table. 873 | @param[in] data Data over which the remainder will be computed 874 | @param[in] size Size of the data, in bytes 875 | @param[in] lookupTable CRC lookup table 876 | @param[in] remainder Running CRC remainder. Can be an initial value or the result of a previous CRC remainder calculation. 877 | @tparam CRCType Integer type for storing the CRC result 878 | @tparam CRCWidth Number of bits in the CRC 879 | @return CRC remainder 880 | */ 881 | template 882 | inline CRCType CRC::CalculateRemainder(const void * data, crcpp_size size, const Table & lookupTable, CRCType remainder) 883 | { 884 | const unsigned char * current = reinterpret_cast(data); 885 | 886 | if (lookupTable.GetParameters().reflectInput) 887 | { 888 | while (size--) 889 | { 890 | #if defined(WIN32) || defined(_WIN32) || defined(WINCE) 891 | // Disable warning about data loss when doing (remainder >> CHAR_BIT) when 892 | // remainder is one byte long. The algorithm is still correct in this case, 893 | // though it's possible that one additional machine instruction will be executed. 894 | # pragma warning (push) 895 | # pragma warning (disable : 4333) 896 | #endif 897 | remainder = static_cast((remainder >> CHAR_BIT) ^ lookupTable[static_cast(remainder ^ *current++)]); 898 | #if defined(WIN32) || defined(_WIN32) || defined(WINCE) 899 | # pragma warning (pop) 900 | #endif 901 | } 902 | } 903 | else if (CRCWidth >= CHAR_BIT) 904 | { 905 | // The conditional expression is used to avoid a -Wshift-count-overflow warning. 906 | static crcpp_constexpr CRCType SHIFT((CRCWidth >= CHAR_BIT) ? static_cast(CRCWidth - CHAR_BIT) : 0); 907 | 908 | while (size--) 909 | { 910 | remainder = static_cast((remainder << CHAR_BIT) ^ lookupTable[static_cast((remainder >> SHIFT) ^ *current++)]); 911 | } 912 | } 913 | else 914 | { 915 | // The conditional expression is used to avoid a -Wshift-count-overflow warning. 916 | static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); 917 | 918 | remainder = static_cast(remainder << SHIFT); 919 | 920 | while (size--) 921 | { 922 | // Note: no need to mask here since remainder is guaranteed to fit in a single byte. 923 | remainder = lookupTable[static_cast(remainder ^ *current++)]; 924 | } 925 | 926 | remainder = static_cast(remainder >> SHIFT); 927 | } 928 | 929 | return remainder; 930 | } 931 | 932 | template 933 | inline CRCType CRC::CalculateRemainderBits(unsigned char byte, crcpp_size numBits, const Parameters & parameters, CRCType remainder) 934 | { 935 | // Slightly different implementations based on the parameters. The current implementations try to eliminate as much 936 | // computation from the inner loop (looping over each bit) as possible. 937 | if (parameters.reflectInput) 938 | { 939 | CRCType polynomial = CRC::Reflect(parameters.polynomial, CRCWidth); 940 | remainder = static_cast(remainder ^ byte); 941 | 942 | // An optimizing compiler might choose to unroll this loop. 943 | for (crcpp_size i = 0; i < numBits; ++i) 944 | { 945 | #ifdef CRCPP_BRANCHLESS 946 | // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: 947 | // if (remainder & 1) 948 | // remainder = (remainder >> 1) ^ polynomial; 949 | // else 950 | // remainder >>= 1; 951 | remainder = static_cast((remainder >> 1) ^ ((remainder & 1) * polynomial)); 952 | #else 953 | remainder = static_cast((remainder & 1) ? ((remainder >> 1) ^ polynomial) : (remainder >> 1)); 954 | #endif 955 | } 956 | } 957 | else if (CRCWidth >= CHAR_BIT) 958 | { 959 | static crcpp_constexpr CRCType CRC_WIDTH_MINUS_ONE(CRCWidth - CRCType(1)); 960 | #ifndef CRCPP_BRANCHLESS 961 | static crcpp_constexpr CRCType CRC_HIGHEST_BIT_MASK(CRCType(1) << CRC_WIDTH_MINUS_ONE); 962 | #endif 963 | // The conditional expression is used to avoid a -Wshift-count-overflow warning. 964 | static crcpp_constexpr CRCType SHIFT((CRCWidth >= CHAR_BIT) ? static_cast(CRCWidth - CHAR_BIT) : 0); 965 | 966 | remainder = static_cast(remainder ^ (static_cast(byte) << SHIFT)); 967 | 968 | // An optimizing compiler might choose to unroll this loop. 969 | for (crcpp_size i = 0; i < numBits; ++i) 970 | { 971 | #ifdef CRCPP_BRANCHLESS 972 | // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: 973 | // if (remainder & CRC_HIGHEST_BIT_MASK) 974 | // remainder = (remainder << 1) ^ parameters.polynomial; 975 | // else 976 | // remainder <<= 1; 977 | remainder = static_cast((remainder << 1) ^ (((remainder >> CRC_WIDTH_MINUS_ONE) & 1) * parameters.polynomial)); 978 | #else 979 | remainder = static_cast((remainder & CRC_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ parameters.polynomial) : (remainder << 1)); 980 | #endif 981 | } 982 | } 983 | else 984 | { 985 | static crcpp_constexpr CRCType CHAR_BIT_MINUS_ONE(CHAR_BIT - 1); 986 | #ifndef CRCPP_BRANCHLESS 987 | static crcpp_constexpr CRCType CHAR_BIT_HIGHEST_BIT_MASK(CRCType(1) << CHAR_BIT_MINUS_ONE); 988 | #endif 989 | // The conditional expression is used to avoid a -Wshift-count-overflow warning. 990 | static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); 991 | 992 | CRCType polynomial = static_cast(parameters.polynomial << SHIFT); 993 | remainder = static_cast((remainder << SHIFT) ^ byte); 994 | 995 | // An optimizing compiler might choose to unroll this loop. 996 | for (crcpp_size i = 0; i < numBits; ++i) 997 | { 998 | #ifdef CRCPP_BRANCHLESS 999 | // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: 1000 | // if (remainder & CHAR_BIT_HIGHEST_BIT_MASK) 1001 | // remainder = (remainder << 1) ^ polynomial; 1002 | // else 1003 | // remainder <<= 1; 1004 | remainder = static_cast((remainder << 1) ^ (((remainder >> CHAR_BIT_MINUS_ONE) & 1) * polynomial)); 1005 | #else 1006 | remainder = static_cast((remainder & CHAR_BIT_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ polynomial) : (remainder << 1)); 1007 | #endif 1008 | } 1009 | 1010 | remainder = static_cast(remainder >> SHIFT); 1011 | } 1012 | 1013 | return remainder; 1014 | } 1015 | 1016 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1017 | /** 1018 | @brief Returns a set of parameters for CRC-4 ITU. 1019 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1020 | @note CRC-4 ITU has the following parameters and check value: 1021 | - polynomial = 0x3 1022 | - initial value = 0x0 1023 | - final XOR = 0x0 1024 | - reflect input = true 1025 | - reflect output = true 1026 | - check value = 0x7 1027 | @return CRC-4 ITU parameters 1028 | */ 1029 | inline const CRC::Parameters & CRC::CRC_4_ITU() 1030 | { 1031 | static const Parameters parameters = { 0x3, 0x0, 0x0, true, true }; 1032 | return parameters; 1033 | } 1034 | 1035 | /** 1036 | @brief Returns a set of parameters for CRC-5 EPC. 1037 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1038 | @note CRC-5 EPC has the following parameters and check value: 1039 | - polynomial = 0x09 1040 | - initial value = 0x09 1041 | - final XOR = 0x00 1042 | - reflect input = false 1043 | - reflect output = false 1044 | - check value = 0x00 1045 | @return CRC-5 EPC parameters 1046 | */ 1047 | inline const CRC::Parameters & CRC::CRC_5_EPC() 1048 | { 1049 | static const Parameters parameters = { 0x09, 0x09, 0x00, false, false }; 1050 | return parameters; 1051 | } 1052 | 1053 | /** 1054 | @brief Returns a set of parameters for CRC-5 ITU. 1055 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1056 | @note CRC-5 ITU has the following parameters and check value: 1057 | - polynomial = 0x15 1058 | - initial value = 0x00 1059 | - final XOR = 0x00 1060 | - reflect input = true 1061 | - reflect output = true 1062 | - check value = 0x07 1063 | @return CRC-5 ITU parameters 1064 | */ 1065 | inline const CRC::Parameters & CRC::CRC_5_ITU() 1066 | { 1067 | static const Parameters parameters = { 0x15, 0x00, 0x00, true, true }; 1068 | return parameters; 1069 | } 1070 | 1071 | /** 1072 | @brief Returns a set of parameters for CRC-5 USB. 1073 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1074 | @note CRC-5 USB has the following parameters and check value: 1075 | - polynomial = 0x05 1076 | - initial value = 0x1F 1077 | - final XOR = 0x1F 1078 | - reflect input = true 1079 | - reflect output = true 1080 | - check value = 0x19 1081 | @return CRC-5 USB parameters 1082 | */ 1083 | inline const CRC::Parameters & CRC::CRC_5_USB() 1084 | { 1085 | static const Parameters parameters = { 0x05, 0x1F, 0x1F, true, true }; 1086 | return parameters; 1087 | } 1088 | 1089 | /** 1090 | @brief Returns a set of parameters for CRC-6 CDMA2000-A. 1091 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1092 | @note CRC-6 CDMA2000-A has the following parameters and check value: 1093 | - polynomial = 0x27 1094 | - initial value = 0x3F 1095 | - final XOR = 0x00 1096 | - reflect input = false 1097 | - reflect output = false 1098 | - check value = 0x0D 1099 | @return CRC-6 CDMA2000-A parameters 1100 | */ 1101 | inline const CRC::Parameters & CRC::CRC_6_CDMA2000A() 1102 | { 1103 | static const Parameters parameters = { 0x27, 0x3F, 0x00, false, false }; 1104 | return parameters; 1105 | } 1106 | 1107 | /** 1108 | @brief Returns a set of parameters for CRC-6 CDMA2000-B. 1109 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1110 | @note CRC-6 CDMA2000-A has the following parameters and check value: 1111 | - polynomial = 0x07 1112 | - initial value = 0x3F 1113 | - final XOR = 0x00 1114 | - reflect input = false 1115 | - reflect output = false 1116 | - check value = 0x3B 1117 | @return CRC-6 CDMA2000-B parameters 1118 | */ 1119 | inline const CRC::Parameters & CRC::CRC_6_CDMA2000B() 1120 | { 1121 | static const Parameters parameters = { 0x07, 0x3F, 0x00, false, false }; 1122 | return parameters; 1123 | } 1124 | 1125 | /** 1126 | @brief Returns a set of parameters for CRC-6 ITU. 1127 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1128 | @note CRC-6 ITU has the following parameters and check value: 1129 | - polynomial = 0x03 1130 | - initial value = 0x00 1131 | - final XOR = 0x00 1132 | - reflect input = true 1133 | - reflect output = true 1134 | - check value = 0x06 1135 | @return CRC-6 ITU parameters 1136 | */ 1137 | inline const CRC::Parameters & CRC::CRC_6_ITU() 1138 | { 1139 | static const Parameters parameters = { 0x03, 0x00, 0x00, true, true }; 1140 | return parameters; 1141 | } 1142 | 1143 | /** 1144 | @brief Returns a set of parameters for CRC-6 NR. 1145 | @note The parameters are static and are delayed-constructed to reduce memory 1146 | footprint. 1147 | @note CRC-6 NR has the following parameters and check value: 1148 | - polynomial = 0x21 1149 | - initial value = 0x00 1150 | - final XOR = 0x00 1151 | - reflect input = false 1152 | - reflect output = false 1153 | - check value = 0x15 1154 | @return CRC-6 NR parameters 1155 | */ 1156 | inline const CRC::Parameters & CRC::CRC_6_NR() 1157 | { 1158 | static const Parameters parameters = { 0x21, 0x00, 0x00, false, false }; 1159 | return parameters; 1160 | } 1161 | 1162 | /** 1163 | @brief Returns a set of parameters for CRC-7 JEDEC. 1164 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1165 | @note CRC-7 JEDEC has the following parameters and check value: 1166 | - polynomial = 0x09 1167 | - initial value = 0x00 1168 | - final XOR = 0x00 1169 | - reflect input = false 1170 | - reflect output = false 1171 | - check value = 0x75 1172 | @return CRC-7 JEDEC parameters 1173 | */ 1174 | inline const CRC::Parameters & CRC::CRC_7() 1175 | { 1176 | static const Parameters parameters = { 0x09, 0x00, 0x00, false, false }; 1177 | return parameters; 1178 | } 1179 | #endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1180 | 1181 | /** 1182 | @brief Returns a set of parameters for CRC-8 SMBus. 1183 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1184 | @note CRC-8 SMBus has the following parameters and check value: 1185 | - polynomial = 0x07 1186 | - initial value = 0x00 1187 | - final XOR = 0x00 1188 | - reflect input = false 1189 | - reflect output = false 1190 | - check value = 0xF4 1191 | @return CRC-8 SMBus parameters 1192 | */ 1193 | inline const CRC::Parameters & CRC::CRC_8() 1194 | { 1195 | static const Parameters parameters = { 0x07, 0x00, 0x00, false, false }; 1196 | return parameters; 1197 | } 1198 | 1199 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1200 | /** 1201 | @brief Returns a set of parameters for CRC-8 EBU (aka CRC-8 AES). 1202 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1203 | @note CRC-8 EBU has the following parameters and check value: 1204 | - polynomial = 0x1D 1205 | - initial value = 0xFF 1206 | - final XOR = 0x00 1207 | - reflect input = true 1208 | - reflect output = true 1209 | - check value = 0x97 1210 | @return CRC-8 EBU parameters 1211 | */ 1212 | inline const CRC::Parameters & CRC::CRC_8_EBU() 1213 | { 1214 | static const Parameters parameters = { 0x1D, 0xFF, 0x00, true, true }; 1215 | return parameters; 1216 | } 1217 | 1218 | /** 1219 | @brief Returns a set of parameters for CRC-8 MAXIM (aka CRC-8 DOW-CRC). 1220 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1221 | @note CRC-8 MAXIM has the following parameters and check value: 1222 | - polynomial = 0x31 1223 | - initial value = 0x00 1224 | - final XOR = 0x00 1225 | - reflect input = true 1226 | - reflect output = true 1227 | - check value = 0xA1 1228 | @return CRC-8 MAXIM parameters 1229 | */ 1230 | inline const CRC::Parameters & CRC::CRC_8_MAXIM() 1231 | { 1232 | static const Parameters parameters = { 0x31, 0x00, 0x00, true, true }; 1233 | return parameters; 1234 | } 1235 | 1236 | /** 1237 | @brief Returns a set of parameters for CRC-8 WCDMA. 1238 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1239 | @note CRC-8 WCDMA has the following parameters and check value: 1240 | - polynomial = 0x9B 1241 | - initial value = 0x00 1242 | - final XOR = 0x00 1243 | - reflect input = true 1244 | - reflect output = true 1245 | - check value = 0x25 1246 | @return CRC-8 WCDMA parameters 1247 | */ 1248 | inline const CRC::Parameters & CRC::CRC_8_WCDMA() 1249 | { 1250 | static const Parameters parameters = { 0x9B, 0x00, 0x00, true, true }; 1251 | return parameters; 1252 | } 1253 | 1254 | /** 1255 | @brief Returns a set of parameters for CRC-8 LTE. 1256 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1257 | @note CRC-8 LTE has the following parameters and check value: 1258 | - polynomial = 0x9B 1259 | - initial value = 0x00 1260 | - final XOR = 0x00 1261 | - reflect input = false 1262 | - reflect output = false 1263 | - check value = 0xEA 1264 | @return CRC-8 LTE parameters 1265 | */ 1266 | inline const CRC::Parameters & CRC::CRC_8_LTE() 1267 | { 1268 | static const Parameters parameters = { 0x9B, 0x00, 0x00, false, false }; 1269 | return parameters; 1270 | } 1271 | 1272 | /** 1273 | @brief Returns a set of parameters for CRC-10 ITU. 1274 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1275 | @note CRC-10 ITU has the following parameters and check value: 1276 | - polynomial = 0x233 1277 | - initial value = 0x000 1278 | - final XOR = 0x000 1279 | - reflect input = false 1280 | - reflect output = false 1281 | - check value = 0x199 1282 | @return CRC-10 ITU parameters 1283 | */ 1284 | inline const CRC::Parameters & CRC::CRC_10() 1285 | { 1286 | static const Parameters parameters = { 0x233, 0x000, 0x000, false, false }; 1287 | return parameters; 1288 | } 1289 | 1290 | /** 1291 | @brief Returns a set of parameters for CRC-10 CDMA2000. 1292 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1293 | @note CRC-10 CDMA2000 has the following parameters and check value: 1294 | - polynomial = 0x3D9 1295 | - initial value = 0x3FF 1296 | - final XOR = 0x000 1297 | - reflect input = false 1298 | - reflect output = false 1299 | - check value = 0x233 1300 | @return CRC-10 CDMA2000 parameters 1301 | */ 1302 | inline const CRC::Parameters & CRC::CRC_10_CDMA2000() 1303 | { 1304 | static const Parameters parameters = { 0x3D9, 0x3FF, 0x000, false, false }; 1305 | return parameters; 1306 | } 1307 | 1308 | /** 1309 | @brief Returns a set of parameters for CRC-11 FlexRay. 1310 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1311 | @note CRC-11 FlexRay has the following parameters and check value: 1312 | - polynomial = 0x385 1313 | - initial value = 0x01A 1314 | - final XOR = 0x000 1315 | - reflect input = false 1316 | - reflect output = false 1317 | - check value = 0x5A3 1318 | @return CRC-11 FlexRay parameters 1319 | */ 1320 | inline const CRC::Parameters & CRC::CRC_11() 1321 | { 1322 | static const Parameters parameters = { 0x385, 0x01A, 0x000, false, false }; 1323 | return parameters; 1324 | } 1325 | 1326 | /** 1327 | @brief Returns a set of parameters for CRC-11 NR. 1328 | @note The parameters are static and are delayed-constructed to reduce memory 1329 | footprint. 1330 | @note CRC-11 NR has the following parameters and check value: 1331 | - polynomial = 0x621 1332 | - initial value = 0x000 1333 | - final XOR = 0x000 1334 | - reflect input = false 1335 | - reflect output = false 1336 | - check value = 0x5CA 1337 | @return CRC-11 NR parameters 1338 | */ 1339 | inline const CRC::Parameters & CRC::CRC_11_NR() 1340 | { 1341 | static const Parameters parameters = { 0x621, 0x000, 0x000, false, false }; 1342 | return parameters; 1343 | } 1344 | 1345 | /** 1346 | @brief Returns a set of parameters for CRC-12 CDMA2000. 1347 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1348 | @note CRC-12 CDMA2000 has the following parameters and check value: 1349 | - polynomial = 0xF13 1350 | - initial value = 0xFFF 1351 | - final XOR = 0x000 1352 | - reflect input = false 1353 | - reflect output = false 1354 | - check value = 0xD4D 1355 | @return CRC-12 CDMA2000 parameters 1356 | */ 1357 | inline const CRC::Parameters & CRC::CRC_12_CDMA2000() 1358 | { 1359 | static const Parameters parameters = { 0xF13, 0xFFF, 0x000, false, false }; 1360 | return parameters; 1361 | } 1362 | 1363 | /** 1364 | @brief Returns a set of parameters for CRC-12 DECT (aka CRC-12 X-CRC). 1365 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1366 | @note CRC-12 DECT has the following parameters and check value: 1367 | - polynomial = 0x80F 1368 | - initial value = 0x000 1369 | - final XOR = 0x000 1370 | - reflect input = false 1371 | - reflect output = false 1372 | - check value = 0xF5B 1373 | @return CRC-12 DECT parameters 1374 | */ 1375 | inline const CRC::Parameters & CRC::CRC_12_DECT() 1376 | { 1377 | static const Parameters parameters = { 0x80F, 0x000, 0x000, false, false }; 1378 | return parameters; 1379 | } 1380 | 1381 | /** 1382 | @brief Returns a set of parameters for CRC-12 UMTS (aka CRC-12 3GPP). 1383 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1384 | @note CRC-12 UMTS has the following parameters and check value: 1385 | - polynomial = 0x80F 1386 | - initial value = 0x000 1387 | - final XOR = 0x000 1388 | - reflect input = false 1389 | - reflect output = true 1390 | - check value = 0xDAF 1391 | @return CRC-12 UMTS parameters 1392 | */ 1393 | inline const CRC::Parameters & CRC::CRC_12_UMTS() 1394 | { 1395 | static const Parameters parameters = { 0x80F, 0x000, 0x000, false, true }; 1396 | return parameters; 1397 | } 1398 | 1399 | /** 1400 | @brief Returns a set of parameters for CRC-13 BBC. 1401 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1402 | @note CRC-13 BBC has the following parameters and check value: 1403 | - polynomial = 0x1CF5 1404 | - initial value = 0x0000 1405 | - final XOR = 0x0000 1406 | - reflect input = false 1407 | - reflect output = false 1408 | - check value = 0x04FA 1409 | @return CRC-13 BBC parameters 1410 | */ 1411 | inline const CRC::Parameters & CRC::CRC_13_BBC() 1412 | { 1413 | static const Parameters parameters = { 0x1CF5, 0x0000, 0x0000, false, false }; 1414 | return parameters; 1415 | } 1416 | 1417 | /** 1418 | @brief Returns a set of parameters for CRC-15 CAN. 1419 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1420 | @note CRC-15 CAN has the following parameters and check value: 1421 | - polynomial = 0x4599 1422 | - initial value = 0x0000 1423 | - final XOR = 0x0000 1424 | - reflect input = false 1425 | - reflect output = false 1426 | - check value = 0x059E 1427 | @return CRC-15 CAN parameters 1428 | */ 1429 | inline const CRC::Parameters & CRC::CRC_15() 1430 | { 1431 | static const Parameters parameters = { 0x4599, 0x0000, 0x0000, false, false }; 1432 | return parameters; 1433 | } 1434 | 1435 | /** 1436 | @brief Returns a set of parameters for CRC-15 MPT1327. 1437 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1438 | @note CRC-15 MPT1327 has the following parameters and check value: 1439 | - polynomial = 0x6815 1440 | - initial value = 0x0000 1441 | - final XOR = 0x0001 1442 | - reflect input = false 1443 | - reflect output = false 1444 | - check value = 0x2566 1445 | @return CRC-15 MPT1327 parameters 1446 | */ 1447 | inline const CRC::Parameters & CRC::CRC_15_MPT1327() 1448 | { 1449 | static const Parameters parameters = { 0x6815, 0x0000, 0x0001, false, false }; 1450 | return parameters; 1451 | } 1452 | #endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1453 | 1454 | /** 1455 | @brief Returns a set of parameters for CRC-16 ARC (aka CRC-16 IBM, CRC-16 LHA). 1456 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1457 | @note CRC-16 ARC has the following parameters and check value: 1458 | - polynomial = 0x8005 1459 | - initial value = 0x0000 1460 | - final XOR = 0x0000 1461 | - reflect input = true 1462 | - reflect output = true 1463 | - check value = 0xBB3D 1464 | @return CRC-16 ARC parameters 1465 | */ 1466 | inline const CRC::Parameters & CRC::CRC_16_ARC() 1467 | { 1468 | static const Parameters parameters = { 0x8005, 0x0000, 0x0000, true, true }; 1469 | return parameters; 1470 | } 1471 | 1472 | /** 1473 | @brief Returns a set of parameters for CRC-16 BUYPASS (aka CRC-16 VERIFONE, CRC-16 UMTS). 1474 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1475 | @note CRC-16 BUYPASS has the following parameters and check value: 1476 | - polynomial = 0x8005 1477 | - initial value = 0x0000 1478 | - final XOR = 0x0000 1479 | - reflect input = false 1480 | - reflect output = false 1481 | - check value = 0xFEE8 1482 | @return CRC-16 BUYPASS parameters 1483 | */ 1484 | inline const CRC::Parameters & CRC::CRC_16_BUYPASS() 1485 | { 1486 | static const Parameters parameters = { 0x8005, 0x0000, 0x0000, false, false }; 1487 | return parameters; 1488 | } 1489 | 1490 | /** 1491 | @brief Returns a set of parameters for CRC-16 CCITT FALSE. 1492 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1493 | @note CRC-16 CCITT FALSE has the following parameters and check value: 1494 | - polynomial = 0x1021 1495 | - initial value = 0xFFFF 1496 | - final XOR = 0x0000 1497 | - reflect input = false 1498 | - reflect output = false 1499 | - check value = 0x29B1 1500 | @return CRC-16 CCITT FALSE parameters 1501 | */ 1502 | inline const CRC::Parameters & CRC::CRC_16_CCITTFALSE() 1503 | { 1504 | static const Parameters parameters = { 0x1021, 0xFFFF, 0x0000, false, false }; 1505 | return parameters; 1506 | } 1507 | 1508 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1509 | /** 1510 | @brief Returns a set of parameters for CRC-16 CDMA2000. 1511 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1512 | @note CRC-16 CDMA2000 has the following parameters and check value: 1513 | - polynomial = 0xC867 1514 | - initial value = 0xFFFF 1515 | - final XOR = 0x0000 1516 | - reflect input = false 1517 | - reflect output = false 1518 | - check value = 0x4C06 1519 | @return CRC-16 CDMA2000 parameters 1520 | */ 1521 | inline const CRC::Parameters & CRC::CRC_16_CDMA2000() 1522 | { 1523 | static const Parameters parameters = { 0xC867, 0xFFFF, 0x0000, false, false }; 1524 | return parameters; 1525 | } 1526 | 1527 | /** 1528 | @brief Returns a set of parameters for CRC-16 CMS. 1529 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1530 | @note CRC-16 CMS has the following parameters and check value: 1531 | - polynomial = 0x8005 1532 | - initial value = 0xFFFF 1533 | - final XOR = 0x0000 1534 | - reflect input = false 1535 | - reflect output = false 1536 | - check value = 0xAEE7 1537 | @return CRC-16 CMS parameters 1538 | */ 1539 | inline const CRC::Parameters & CRC::CRC_16_CMS() 1540 | { 1541 | static const Parameters parameters = { 0x8005, 0xFFFF, 0x0000, false, false }; 1542 | return parameters; 1543 | } 1544 | 1545 | /** 1546 | @brief Returns a set of parameters for CRC-16 DECT-R (aka CRC-16 R-CRC). 1547 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1548 | @note CRC-16 DECT-R has the following parameters and check value: 1549 | - polynomial = 0x0589 1550 | - initial value = 0x0000 1551 | - final XOR = 0x0001 1552 | - reflect input = false 1553 | - reflect output = false 1554 | - check value = 0x007E 1555 | @return CRC-16 DECT-R parameters 1556 | */ 1557 | inline const CRC::Parameters & CRC::CRC_16_DECTR() 1558 | { 1559 | static const Parameters parameters = { 0x0589, 0x0000, 0x0001, false, false }; 1560 | return parameters; 1561 | } 1562 | 1563 | /** 1564 | @brief Returns a set of parameters for CRC-16 DECT-X (aka CRC-16 X-CRC). 1565 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1566 | @note CRC-16 DECT-X has the following parameters and check value: 1567 | - polynomial = 0x0589 1568 | - initial value = 0x0000 1569 | - final XOR = 0x0000 1570 | - reflect input = false 1571 | - reflect output = false 1572 | - check value = 0x007F 1573 | @return CRC-16 DECT-X parameters 1574 | */ 1575 | inline const CRC::Parameters & CRC::CRC_16_DECTX() 1576 | { 1577 | static const Parameters parameters = { 0x0589, 0x0000, 0x0000, false, false }; 1578 | return parameters; 1579 | } 1580 | 1581 | /** 1582 | @brief Returns a set of parameters for CRC-16 DNP. 1583 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1584 | @note CRC-16 DNP has the following parameters and check value: 1585 | - polynomial = 0x3D65 1586 | - initial value = 0x0000 1587 | - final XOR = 0xFFFF 1588 | - reflect input = true 1589 | - reflect output = true 1590 | - check value = 0xEA82 1591 | @return CRC-16 DNP parameters 1592 | */ 1593 | inline const CRC::Parameters & CRC::CRC_16_DNP() 1594 | { 1595 | static const Parameters parameters = { 0x3D65, 0x0000, 0xFFFF, true, true }; 1596 | return parameters; 1597 | } 1598 | #endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1599 | 1600 | /** 1601 | @brief Returns a set of parameters for CRC-16 GENIBUS (aka CRC-16 EPC, CRC-16 I-CODE, CRC-16 DARC). 1602 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1603 | @note CRC-16 GENIBUS has the following parameters and check value: 1604 | - polynomial = 0x1021 1605 | - initial value = 0xFFFF 1606 | - final XOR = 0xFFFF 1607 | - reflect input = false 1608 | - reflect output = false 1609 | - check value = 0xD64E 1610 | @return CRC-16 GENIBUS parameters 1611 | */ 1612 | inline const CRC::Parameters & CRC::CRC_16_GENIBUS() 1613 | { 1614 | static const Parameters parameters = { 0x1021, 0xFFFF, 0xFFFF, false, false }; 1615 | return parameters; 1616 | } 1617 | 1618 | /** 1619 | @brief Returns a set of parameters for CRC-16 KERMIT (aka CRC-16 CCITT, CRC-16 CCITT-TRUE). 1620 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1621 | @note CRC-16 KERMIT has the following parameters and check value: 1622 | - polynomial = 0x1021 1623 | - initial value = 0x0000 1624 | - final XOR = 0x0000 1625 | - reflect input = true 1626 | - reflect output = true 1627 | - check value = 0x2189 1628 | @return CRC-16 KERMIT parameters 1629 | */ 1630 | inline const CRC::Parameters & CRC::CRC_16_KERMIT() 1631 | { 1632 | static const Parameters parameters = { 0x1021, 0x0000, 0x0000, true, true }; 1633 | return parameters; 1634 | } 1635 | 1636 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1637 | /** 1638 | @brief Returns a set of parameters for CRC-16 MAXIM. 1639 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1640 | @note CRC-16 MAXIM has the following parameters and check value: 1641 | - polynomial = 0x8005 1642 | - initial value = 0x0000 1643 | - final XOR = 0xFFFF 1644 | - reflect input = true 1645 | - reflect output = true 1646 | - check value = 0x44C2 1647 | @return CRC-16 MAXIM parameters 1648 | */ 1649 | inline const CRC::Parameters & CRC::CRC_16_MAXIM() 1650 | { 1651 | static const Parameters parameters = { 0x8005, 0x0000, 0xFFFF, true, true }; 1652 | return parameters; 1653 | } 1654 | 1655 | /** 1656 | @brief Returns a set of parameters for CRC-16 MODBUS. 1657 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1658 | @note CRC-16 MODBUS has the following parameters and check value: 1659 | - polynomial = 0x8005 1660 | - initial value = 0xFFFF 1661 | - final XOR = 0x0000 1662 | - reflect input = true 1663 | - reflect output = true 1664 | - check value = 0x4B37 1665 | @return CRC-16 MODBUS parameters 1666 | */ 1667 | inline const CRC::Parameters & CRC::CRC_16_MODBUS() 1668 | { 1669 | static const Parameters parameters = { 0x8005, 0xFFFF, 0x0000, true, true }; 1670 | return parameters; 1671 | } 1672 | 1673 | /** 1674 | @brief Returns a set of parameters for CRC-16 T10-DIF. 1675 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1676 | @note CRC-16 T10-DIF has the following parameters and check value: 1677 | - polynomial = 0x8BB7 1678 | - initial value = 0x0000 1679 | - final XOR = 0x0000 1680 | - reflect input = false 1681 | - reflect output = false 1682 | - check value = 0xD0DB 1683 | @return CRC-16 T10-DIF parameters 1684 | */ 1685 | inline const CRC::Parameters & CRC::CRC_16_T10DIF() 1686 | { 1687 | static const Parameters parameters = { 0x8BB7, 0x0000, 0x0000, false, false }; 1688 | return parameters; 1689 | } 1690 | 1691 | /** 1692 | @brief Returns a set of parameters for CRC-16 USB. 1693 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1694 | @note CRC-16 USB has the following parameters and check value: 1695 | - polynomial = 0x8005 1696 | - initial value = 0xFFFF 1697 | - final XOR = 0xFFFF 1698 | - reflect input = true 1699 | - reflect output = true 1700 | - check value = 0xB4C8 1701 | @return CRC-16 USB parameters 1702 | */ 1703 | inline const CRC::Parameters & CRC::CRC_16_USB() 1704 | { 1705 | static const Parameters parameters = { 0x8005, 0xFFFF, 0xFFFF, true, true }; 1706 | return parameters; 1707 | } 1708 | 1709 | #endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1710 | 1711 | /** 1712 | @brief Returns a set of parameters for CRC-16 X-25 (aka CRC-16 IBM-SDLC, CRC-16 ISO-HDLC, CRC-16 B). 1713 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1714 | @note CRC-16 X-25 has the following parameters and check value: 1715 | - polynomial = 0x1021 1716 | - initial value = 0xFFFF 1717 | - final XOR = 0xFFFF 1718 | - reflect input = true 1719 | - reflect output = true 1720 | - check value = 0x906E 1721 | @return CRC-16 X-25 parameters 1722 | */ 1723 | inline const CRC::Parameters & CRC::CRC_16_X25() 1724 | { 1725 | static const Parameters parameters = { 0x1021, 0xFFFF, 0xFFFF, true, true }; 1726 | return parameters; 1727 | } 1728 | 1729 | /** 1730 | @brief Returns a set of parameters for CRC-16 XMODEM (aka CRC-16 ZMODEM, CRC-16 ACORN, CRC-16 LTE). 1731 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1732 | @note CRC-16 XMODEM has the following parameters and check value: 1733 | - polynomial = 0x1021 1734 | - initial value = 0x0000 1735 | - final XOR = 0x0000 1736 | - reflect input = false 1737 | - reflect output = false 1738 | - check value = 0x31C3 1739 | @return CRC-16 XMODEM parameters 1740 | */ 1741 | inline const CRC::Parameters & CRC::CRC_16_XMODEM() 1742 | { 1743 | static const Parameters parameters = { 0x1021, 0x0000, 0x0000, false, false }; 1744 | return parameters; 1745 | } 1746 | 1747 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1748 | /** 1749 | @brief Returns a set of parameters for CRC-17 CAN. 1750 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1751 | @note CRC-17 CAN has the following parameters and check value: 1752 | - polynomial = 0x1685B 1753 | - initial value = 0x00000 1754 | - final XOR = 0x00000 1755 | - reflect input = false 1756 | - reflect output = false 1757 | - check value = 0x04F03 1758 | @return CRC-17 CAN parameters 1759 | */ 1760 | inline const CRC::Parameters & CRC::CRC_17_CAN() 1761 | { 1762 | static const Parameters parameters = { 0x1685B, 0x00000, 0x00000, false, false }; 1763 | return parameters; 1764 | } 1765 | 1766 | /** 1767 | @brief Returns a set of parameters for CRC-21 CAN. 1768 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1769 | @note CRC-21 CAN has the following parameters and check value: 1770 | - polynomial = 0x102899 1771 | - initial value = 0x000000 1772 | - final XOR = 0x000000 1773 | - reflect input = false 1774 | - reflect output = false 1775 | - check value = 0x0ED841 1776 | @return CRC-21 CAN parameters 1777 | */ 1778 | inline const CRC::Parameters & CRC::CRC_21_CAN() 1779 | { 1780 | static const Parameters parameters = { 0x102899, 0x000000, 0x000000, false, false }; 1781 | return parameters; 1782 | } 1783 | 1784 | /** 1785 | @brief Returns a set of parameters for CRC-24 OPENPGP. 1786 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1787 | @note CRC-24 OPENPGP has the following parameters and check value: 1788 | - polynomial = 0x864CFB 1789 | - initial value = 0xB704CE 1790 | - final XOR = 0x000000 1791 | - reflect input = false 1792 | - reflect output = false 1793 | - check value = 0x21CF02 1794 | @return CRC-24 OPENPGP parameters 1795 | */ 1796 | inline const CRC::Parameters & CRC::CRC_24() 1797 | { 1798 | static const Parameters parameters = { 0x864CFB, 0xB704CE, 0x000000, false, false }; 1799 | return parameters; 1800 | } 1801 | 1802 | /** 1803 | @brief Returns a set of parameters for CRC-24 FlexRay-A. 1804 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1805 | @note CRC-24 FlexRay-A has the following parameters and check value: 1806 | - polynomial = 0x5D6DCB 1807 | - initial value = 0xFEDCBA 1808 | - final XOR = 0x000000 1809 | - reflect input = false 1810 | - reflect output = false 1811 | - check value = 0x7979BD 1812 | @return CRC-24 FlexRay-A parameters 1813 | */ 1814 | inline const CRC::Parameters & CRC::CRC_24_FLEXRAYA() 1815 | { 1816 | static const Parameters parameters = { 0x5D6DCB, 0xFEDCBA, 0x000000, false, false }; 1817 | return parameters; 1818 | } 1819 | 1820 | /** 1821 | @brief Returns a set of parameters for CRC-24 FlexRay-B. 1822 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1823 | @note CRC-24 FlexRay-B has the following parameters and check value: 1824 | - polynomial = 0x5D6DCB 1825 | - initial value = 0xABCDEF 1826 | - final XOR = 0x000000 1827 | - reflect input = false 1828 | - reflect output = false 1829 | - check value = 0x1F23B8 1830 | @return CRC-24 FlexRay-B parameters 1831 | */ 1832 | inline const CRC::Parameters & CRC::CRC_24_FLEXRAYB() 1833 | { 1834 | static const Parameters parameters = { 0x5D6DCB, 0xABCDEF, 0x000000, false, false }; 1835 | return parameters; 1836 | } 1837 | 1838 | /** 1839 | @brief Returns a set of parameters for CRC-24 LTE-A/NR-A. 1840 | @note The parameters are static and are delayed-constructed to reduce memory 1841 | footprint. 1842 | @note CRC-24 LTE-A has the following parameters and check value: 1843 | - polynomial = 0x864CFB 1844 | - initial value = 0x000000 1845 | - final XOR = 0x000000 1846 | - reflect input = false 1847 | - reflect output = false 1848 | - check value = 0xCDE703 1849 | @return CRC-24 LTE-A parameters 1850 | */ 1851 | inline const CRC::Parameters & CRC::CRC_24_LTEA() 1852 | { 1853 | static const Parameters parameters = { 0x864CFB, 0x000000, 0x000000, false, false }; 1854 | return parameters; 1855 | } 1856 | 1857 | /** 1858 | @brief Returns a set of parameters for CRC-24 LTE-B/NR-B. 1859 | @note The parameters are static and are delayed-constructed to reduce memory 1860 | footprint. 1861 | @note CRC-24 LTE-B has the following parameters and check value: 1862 | - polynomial = 0x800063 1863 | - initial value = 0x000000 1864 | - final XOR = 0x000000 1865 | - reflect input = false 1866 | - reflect output = false 1867 | - check value = 0x23EF52 1868 | @return CRC-24 LTE-B parameters 1869 | */ 1870 | inline const CRC::Parameters & CRC::CRC_24_LTEB() 1871 | { 1872 | static const Parameters parameters = { 0x800063, 0x000000, 0x000000, false, false }; 1873 | return parameters; 1874 | } 1875 | 1876 | /** 1877 | @brief Returns a set of parameters for CRC-24 NR-C. 1878 | @note The parameters are static and are delayed-constructed to reduce memory 1879 | footprint. 1880 | @note CRC-24 NR-C has the following parameters and check value: 1881 | - polynomial = 0xB2B117 1882 | - initial value = 0x000000 1883 | - final XOR = 0x000000 1884 | - reflect input = false 1885 | - reflect output = false 1886 | - check value = 0xF48279 1887 | @return CRC-24 NR-C parameters 1888 | */ 1889 | inline const CRC::Parameters & CRC::CRC_24_NRC() 1890 | { 1891 | static const Parameters parameters = { 0xB2B117, 0x000000, 0x000000, false, false }; 1892 | return parameters; 1893 | } 1894 | 1895 | /** 1896 | @brief Returns a set of parameters for CRC-30 CDMA. 1897 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1898 | @note CRC-30 CDMA has the following parameters and check value: 1899 | - polynomial = 0x2030B9C7 1900 | - initial value = 0x3FFFFFFF 1901 | - final XOR = 0x00000000 1902 | - reflect input = false 1903 | - reflect output = false 1904 | - check value = 0x3B3CB540 1905 | @return CRC-30 CDMA parameters 1906 | */ 1907 | inline const CRC::Parameters & CRC::CRC_30() 1908 | { 1909 | static const Parameters parameters = { 0x2030B9C7, 0x3FFFFFFF, 0x00000000, false, false }; 1910 | return parameters; 1911 | } 1912 | #endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1913 | 1914 | /** 1915 | @brief Returns a set of parameters for CRC-32 (aka CRC-32 ADCCP, CRC-32 PKZip). 1916 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1917 | @note CRC-32 has the following parameters and check value: 1918 | - polynomial = 0x04C11DB7 1919 | - initial value = 0xFFFFFFFF 1920 | - final XOR = 0xFFFFFFFF 1921 | - reflect input = true 1922 | - reflect output = true 1923 | - check value = 0xCBF43926 1924 | @return CRC-32 parameters 1925 | */ 1926 | inline const CRC::Parameters & CRC::CRC_32() 1927 | { 1928 | static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true }; 1929 | return parameters; 1930 | } 1931 | 1932 | /** 1933 | @brief Returns a set of parameters for CRC-32 BZIP2 (aka CRC-32 AAL5, CRC-32 DECT-B, CRC-32 B-CRC). 1934 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1935 | @note CRC-32 BZIP2 has the following parameters and check value: 1936 | - polynomial = 0x04C11DB7 1937 | - initial value = 0xFFFFFFFF 1938 | - final XOR = 0xFFFFFFFF 1939 | - reflect input = false 1940 | - reflect output = false 1941 | - check value = 0xFC891918 1942 | @return CRC-32 BZIP2 parameters 1943 | */ 1944 | inline const CRC::Parameters & CRC::CRC_32_BZIP2() 1945 | { 1946 | static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, false, false }; 1947 | return parameters; 1948 | } 1949 | 1950 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 1951 | /** 1952 | @brief Returns a set of parameters for CRC-32 C (aka CRC-32 ISCSI, CRC-32 Castagnoli, CRC-32 Interlaken). 1953 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1954 | @note CRC-32 C has the following parameters and check value: 1955 | - polynomial = 0x1EDC6F41 1956 | - initial value = 0xFFFFFFFF 1957 | - final XOR = 0xFFFFFFFF 1958 | - reflect input = true 1959 | - reflect output = true 1960 | - check value = 0xE3069283 1961 | @return CRC-32 C parameters 1962 | */ 1963 | inline const CRC::Parameters & CRC::CRC_32_C() 1964 | { 1965 | static const Parameters parameters = { 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true }; 1966 | return parameters; 1967 | } 1968 | #endif 1969 | 1970 | /** 1971 | @brief Returns a set of parameters for CRC-32 MPEG-2. 1972 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1973 | @note CRC-32 MPEG-2 has the following parameters and check value: 1974 | - polynomial = 0x04C11DB7 1975 | - initial value = 0xFFFFFFFF 1976 | - final XOR = 0x00000000 1977 | - reflect input = false 1978 | - reflect output = false 1979 | - check value = 0x0376E6E7 1980 | @return CRC-32 MPEG-2 parameters 1981 | */ 1982 | inline const CRC::Parameters & CRC::CRC_32_MPEG2() 1983 | { 1984 | static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0x00000000, false, false }; 1985 | return parameters; 1986 | } 1987 | 1988 | /** 1989 | @brief Returns a set of parameters for CRC-32 POSIX. 1990 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 1991 | @note CRC-32 POSIX has the following parameters and check value: 1992 | - polynomial = 0x04C11DB7 1993 | - initial value = 0x00000000 1994 | - final XOR = 0xFFFFFFFF 1995 | - reflect input = false 1996 | - reflect output = false 1997 | - check value = 0x765E7680 1998 | @return CRC-32 POSIX parameters 1999 | */ 2000 | inline const CRC::Parameters & CRC::CRC_32_POSIX() 2001 | { 2002 | static const Parameters parameters = { 0x04C11DB7, 0x00000000, 0xFFFFFFFF, false, false }; 2003 | return parameters; 2004 | } 2005 | 2006 | #ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 2007 | /** 2008 | @brief Returns a set of parameters for CRC-32 Q. 2009 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 2010 | @note CRC-32 Q has the following parameters and check value: 2011 | - polynomial = 0x814141AB 2012 | - initial value = 0x00000000 2013 | - final XOR = 0x00000000 2014 | - reflect input = false 2015 | - reflect output = false 2016 | - check value = 0x3010BF7F 2017 | @return CRC-32 Q parameters 2018 | */ 2019 | inline const CRC::Parameters & CRC::CRC_32_Q() 2020 | { 2021 | static const Parameters parameters = { 0x814141AB, 0x00000000, 0x00000000, false, false }; 2022 | return parameters; 2023 | } 2024 | 2025 | /** 2026 | @brief Returns a set of parameters for CRC-40 GSM. 2027 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 2028 | @note CRC-40 GSM has the following parameters and check value: 2029 | - polynomial = 0x0004820009 2030 | - initial value = 0x0000000000 2031 | - final XOR = 0xFFFFFFFFFF 2032 | - reflect input = false 2033 | - reflect output = false 2034 | - check value = 0xD4164FC646 2035 | @return CRC-40 GSM parameters 2036 | */ 2037 | inline const CRC::Parameters & CRC::CRC_40_GSM() 2038 | { 2039 | static const Parameters parameters = { 0x0004820009, 0x0000000000, 0xFFFFFFFFFF, false, false }; 2040 | return parameters; 2041 | } 2042 | 2043 | /** 2044 | @brief Returns a set of parameters for CRC-64 ECMA. 2045 | @note The parameters are static and are delayed-constructed to reduce memory footprint. 2046 | @note CRC-64 ECMA has the following parameters and check value: 2047 | - polynomial = 0x42F0E1EBA9EA3693 2048 | - initial value = 0x0000000000000000 2049 | - final XOR = 0x0000000000000000 2050 | - reflect input = false 2051 | - reflect output = false 2052 | - check value = 0x6C40DF5F0B497347 2053 | @return CRC-64 ECMA parameters 2054 | */ 2055 | inline const CRC::Parameters & CRC::CRC_64() 2056 | { 2057 | static const Parameters parameters = { 0x42F0E1EBA9EA3693, 0x0000000000000000, 0x0000000000000000, false, false }; 2058 | return parameters; 2059 | } 2060 | #endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS 2061 | 2062 | #ifdef CRCPP_USE_NAMESPACE 2063 | } 2064 | #endif 2065 | 2066 | #endif // CRCPP_CRC_H_ 2067 | --------------------------------------------------------------------------------