├── .gitignore ├── CMakeLists.txt ├── Makefile.comm ├── README.md ├── crc ├── Makefile ├── crc16.c ├── crc16.h ├── crc32.c ├── crc32.h ├── crc64.c ├── crc64.h ├── crc8.c ├── crc8.h ├── crc_poly.c ├── crc_poly.h ├── crchash.cpp └── crchash.h └── unit-test ├── Makefile ├── crc_test.cpp └── ut ├── test_harness.cpp └── test_harness.h /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.dylib 11 | 12 | # cmake 13 | 14 | CMakeLists.txt.user 15 | CMakeCache.txt 16 | CMakeFiles 17 | CMakeScripts 18 | Testing 19 | Makefile 20 | cmake_install.cmake 21 | install_manifest.txt 22 | compile_commands.json 23 | CTestTestfile.cmake 24 | _deps 25 | 26 | 27 | # git 28 | *.orig 29 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(DEFINED CRC_LIBRARY) 2 | return() 3 | else() 4 | set(CRC_LIBRARY 1) 5 | endif() 6 | 7 | cmake_minimum_required(VERSION 3.1) 8 | project(crc) 9 | 10 | if(TARGET ${PROJECT_NAME}) 11 | message("The ${PROJECT_NAME} arledy included in main Project") 12 | return() 13 | endif() 14 | 15 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 16 | set(CMAKE_CXX_STANDARD 17) 17 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 18 | option(BUILD_SHARED_LIBS "Enable or disable shared libraries" OFF) 19 | option(CRC_TESTS "Enable tests of the ${PROJECT_NAME} library" OFF) 20 | 21 | file(GLOB SOURCE_CPP 22 | "crc/*.h" 23 | "crc/*.cpp" 24 | "crc/*.c" 25 | ) 26 | 27 | add_library(${PROJECT_NAME} ${SOURCE_CPP}) 28 | target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}) 29 | 30 | 31 | if (CRC_TESTS) 32 | file(GLOB SOURCE_CPP_TEST 33 | "unit-test/*.h" 34 | "unit-test/*.cpp" 35 | "unit-test/*.c" 36 | 37 | "unit-test/ut/*.h" 38 | "unit-test/ut/*.cpp" 39 | "unit-test/ut/*.c" 40 | ) 41 | 42 | add_executable(${PROJECT_NAME}_test ${SOURCE_CPP_TEST}) 43 | target_link_libraries(${PROJECT_NAME}_test PUBLIC ${PROJECT_NAME}) 44 | enable_testing() 45 | add_test(NAME crc 46 | COMMAND ${PROJECT_NAME}_test) 47 | endif() 48 | -------------------------------------------------------------------------------- /Makefile.comm: -------------------------------------------------------------------------------- 1 | #CFLAGS = -DDEBUG_LOG -D_DEBUG 2 | #CFLAGS = -DDEBUG_LOG 3 | CFLAGS = -DLINUX 4 | 5 | CC=gcc -std=c++11 -g -O3 $(CFLAGS) 6 | CC=gcc -std=c++11 -g $(CFLAGS) 7 | CCC=gcc -std=c++11 -g $(CFLAGS) 8 | SHARED_FLAG = -fPIC -shared 9 | 10 | %.o : %.cpp 11 | $(CC) $(INC) -c $< -o $@ 12 | %.o : %.c 13 | $(CC) $(INC) -c $< -o $@ 14 | %.o : %.cc 15 | $(CC) $(INC) -c $< -o $@ 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # crc 2 | crc16/crc32/crc64 3 | 4 | ## Build 5 | 6 | ``` bash 7 | git clone https://github.com/gityf/crc.git 8 | mkdir build 9 | cd build 10 | cmake .. -DBUILD_SHARED_LIBS=1 -DCRC_TESTS=1 11 | make 12 | ``` 13 | 14 | ## Testing 15 | 16 | ``` bash 17 | ./crc_test 18 | [ RUN ] ==== Test CRC8Test.BasicTest 19 | [ RUN ] ==== Test CRC16Test.BasicTest 20 | [ RUN ] ==== Test CRC32Test.BasicTest 21 | [ RUN ] ==== Test CRC64Test.BasicTest 22 | [ RUN ] ==== Test CRC8PolyTest.BasicTest 23 | [ RUN ] ==== Test CRC16PolyTest.BasicTest 24 | [ RUN ] ==== Test CRC32PolyTest.BasicTest 25 | [ PASS ] ==== PASSED 7 tests 26 | [ NOPASS ] ==== ERROR 0 tests 27 | 28 | ``` 29 | 30 | ## Include 31 | 32 | ### Cmake build system 33 | 34 | ``` cmake 35 | add_subdirectory(crc) 36 | 37 | target_link_libraries(${PROJECT_NAME} PUBLIC crc) 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /crc/Makefile: -------------------------------------------------------------------------------- 1 | include ../Makefile.comm 2 | 3 | INC += -I. 4 | 5 | SOURCES = $(foreach d,.,$(wildcard $(d)/*.c)) 6 | OBJS = $(patsubst %.c, %.o, $(SOURCES)) 7 | OBJS += crchash.o 8 | 9 | CC += $(SHARED_FLAG) 10 | all : libcrc.a 11 | libcrc.a : $(OBJS) 12 | ar -rus $@ $^ 13 | @echo "" 14 | @echo "+--------------------------------------------+" 15 | @echo "| Finish compilation |" 16 | @echo "+--------------------------------------------+" 17 | @echo "| Thanks using libcrc.a |" 18 | @echo "| copyright(c)Wang Yaofu voipman@qq.com |" 19 | @echo "+--------------------------------------------+" 20 | 21 | clean: 22 | rm -rf *.o *.a 23 | 24 | -------------------------------------------------------------------------------- /crc/crc16.c: -------------------------------------------------------------------------------- 1 | #include "crc16.h" 2 | 3 | /* 4 | * The crc32 is licensed under the Apache License, Version 2.0, and a copy of the license is included in this file. 5 | * CRC16 implementation according to CCITT standards. 6 | * 7 | * The XMODEM CRC 16 algorithm, using the following parameters: 8 | * 9 | * Name : "XMODEM", also known as "ZMODEM", "CRC-16/ACORN" 10 | * Width : 16 bit 11 | * Poly : 1021 (That is actually x^16 + x^12 + x^5 + 1) 12 | * Initialization : 0000 13 | * Reflect Input byte : False 14 | * Reflect Output CRC : False 15 | * Xor constant to output CRC : 0000 16 | * Output for "123456789" : 31C3 17 | */ 18 | 19 | static const uint16_t crc16tab[256]= { 20 | 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, 21 | 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, 22 | 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, 23 | 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, 24 | 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, 25 | 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, 26 | 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, 27 | 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, 28 | 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, 29 | 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, 30 | 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, 31 | 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, 32 | 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, 33 | 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, 34 | 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, 35 | 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, 36 | 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, 37 | 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, 38 | 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, 39 | 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, 40 | 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, 41 | 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, 42 | 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, 43 | 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, 44 | 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, 45 | 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, 46 | 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, 47 | 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, 48 | 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, 49 | 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, 50 | 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, 51 | 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 52 | }; 53 | 54 | uint16_t crc16(const unsigned char *buf, size_t len) { 55 | int counter; 56 | uint16_t crc = 0; 57 | for (counter = 0; counter < len; counter++) 58 | crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *buf++)&0x00FF]; 59 | return crc; 60 | } 61 | -------------------------------------------------------------------------------- /crc/crc16.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRC_CRC16_H 2 | #define _CRC_CRC16_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif /* __cplusplus */ 7 | 8 | #include 9 | #include 10 | 11 | uint16_t crc16(const unsigned char *buf, size_t len); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif /* __cplusplus */ 16 | #endif 17 | -------------------------------------------------------------------------------- /crc/crc32.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** The crc32 is licensed under the Apache License, Version 2.0, and a copy of the license is included in this file. 3 | ** 4 | ** Author:Wang Yaofu voipman@qq.com 5 | ** Description: The source file of class crc32. 6 | ** CRC32 implementation according to IEEE standards. 7 | ** Polynomials are represented in LSB-first form 8 | ** following parameters: 9 | ** Width : 32 bit 10 | ** Poly : 0xedb88320 11 | ** Output for "123456789" : 0xCBF43926 12 | */ 13 | #include 14 | #include "crc32.h" 15 | static uint32_t crc32_tab[] = 16 | { 17 | 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 18 | 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 19 | 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 20 | 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 21 | 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 22 | 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 23 | 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 24 | 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 25 | 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 26 | 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 27 | 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 28 | 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 29 | 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 30 | 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 31 | 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 32 | 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 33 | 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 34 | 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 35 | 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 36 | 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 37 | 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 38 | 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 39 | 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 40 | 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 41 | 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 42 | 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 43 | 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 44 | 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 45 | 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 46 | 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 47 | 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 48 | 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 49 | 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 50 | 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 51 | 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 52 | 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 53 | 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 54 | 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 55 | 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 56 | 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 57 | 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 58 | 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 59 | 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 60 | 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 61 | 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 62 | 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 63 | 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 64 | 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 65 | 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 66 | 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 67 | 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 68 | 0x2d02ef8dL 69 | }; 70 | 71 | /* crc32 hash */ 72 | uint32_t crc32(const unsigned char *s, size_t len) 73 | { 74 | int i; 75 | uint32_t crc32val = 0; 76 | crc32val ^= 0xFFFFFFFF; 77 | 78 | for (i = 0; i < len; i++) { 79 | crc32val = crc32_tab[(crc32val ^ s[i]) & 0xFF] ^ ((crc32val >> 8) & 0x00FFFFFF); 80 | } 81 | 82 | return crc32val ^ 0xFFFFFFFF; 83 | } 84 | -------------------------------------------------------------------------------- /crc/crc32.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRC_CRC32_H 2 | #define _CRC_CRC32_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif /* __cplusplus */ 7 | 8 | #include 9 | #include 10 | 11 | uint32_t crc32(const unsigned char *s, size_t len); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif /* __cplusplus */ 16 | #endif 17 | -------------------------------------------------------------------------------- /crc/crc64.c: -------------------------------------------------------------------------------- 1 | /* Redis uses the CRC64 variant with "Jones" coefficients and init value of 0. 2 | * 3 | * Specification of this CRC64 variant follows: 4 | * Name: crc-64-jones 5 | * Width: 64 bites 6 | * Poly: 0xad93d23594c935a9 7 | * Reflected In: True 8 | * Xor_In: 0xffffffffffffffff 9 | * Reflected_Out: True 10 | * Xor_Out: 0x0 11 | * Check("123456789"): 0xe9c6d914c4b8d9ca 12 | * 13 | * Copyright (c) 2012, Salvatore Sanfilippo 14 | * All rights reserved. 15 | * 16 | * Redistribution and use in source and binary forms, with or without 17 | * modification, are permitted provided that the following conditions are met: 18 | * 19 | * * Redistributions of source code must retain the above copyright notice, 20 | * this list of conditions and the following disclaimer. 21 | * * Redistributions in binary form must reproduce the above copyright 22 | * notice, this list of conditions and the following disclaimer in the 23 | * documentation and/or other materials provided with the distribution. 24 | * * Neither the name of Redis nor the names of its contributors may be used 25 | * to endorse or promote products derived from this software without 26 | * specific prior written permission. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 29 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 30 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 31 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 32 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 | * POSSIBILITY OF SUCH DAMAGE. */ 39 | 40 | #include "crc64.h" 41 | 42 | static const uint64_t crc64_tab[256] = { 43 | 0x0000000000000000ULL, 0x7ad870c830358979ULL, 44 | 0xf5b0e190606b12f2ULL, 0x8f689158505e9b8bULL, 45 | 0xc038e5739841b68fULL, 0xbae095bba8743ff6ULL, 46 | 0x358804e3f82aa47dULL, 0x4f50742bc81f2d04ULL, 47 | 0xab28ecb46814fe75ULL, 0xd1f09c7c5821770cULL, 48 | 0x5e980d24087fec87ULL, 0x24407dec384a65feULL, 49 | 0x6b1009c7f05548faULL, 0x11c8790fc060c183ULL, 50 | 0x9ea0e857903e5a08ULL, 0xe478989fa00bd371ULL, 51 | 0x7d08ff3b88be6f81ULL, 0x07d08ff3b88be6f8ULL, 52 | 0x88b81eabe8d57d73ULL, 0xf2606e63d8e0f40aULL, 53 | 0xbd301a4810ffd90eULL, 0xc7e86a8020ca5077ULL, 54 | 0x4880fbd87094cbfcULL, 0x32588b1040a14285ULL, 55 | 0xd620138fe0aa91f4ULL, 0xacf86347d09f188dULL, 56 | 0x2390f21f80c18306ULL, 0x594882d7b0f40a7fULL, 57 | 0x1618f6fc78eb277bULL, 0x6cc0863448deae02ULL, 58 | 0xe3a8176c18803589ULL, 0x997067a428b5bcf0ULL, 59 | 0xfa11fe77117cdf02ULL, 0x80c98ebf2149567bULL, 60 | 0x0fa11fe77117cdf0ULL, 0x75796f2f41224489ULL, 61 | 0x3a291b04893d698dULL, 0x40f16bccb908e0f4ULL, 62 | 0xcf99fa94e9567b7fULL, 0xb5418a5cd963f206ULL, 63 | 0x513912c379682177ULL, 0x2be1620b495da80eULL, 64 | 0xa489f35319033385ULL, 0xde51839b2936bafcULL, 65 | 0x9101f7b0e12997f8ULL, 0xebd98778d11c1e81ULL, 66 | 0x64b116208142850aULL, 0x1e6966e8b1770c73ULL, 67 | 0x8719014c99c2b083ULL, 0xfdc17184a9f739faULL, 68 | 0x72a9e0dcf9a9a271ULL, 0x08719014c99c2b08ULL, 69 | 0x4721e43f0183060cULL, 0x3df994f731b68f75ULL, 70 | 0xb29105af61e814feULL, 0xc849756751dd9d87ULL, 71 | 0x2c31edf8f1d64ef6ULL, 0x56e99d30c1e3c78fULL, 72 | 0xd9810c6891bd5c04ULL, 0xa3597ca0a188d57dULL, 73 | 0xec09088b6997f879ULL, 0x96d1784359a27100ULL, 74 | 0x19b9e91b09fcea8bULL, 0x636199d339c963f2ULL, 75 | 0xdf7adabd7a6e2d6fULL, 0xa5a2aa754a5ba416ULL, 76 | 0x2aca3b2d1a053f9dULL, 0x50124be52a30b6e4ULL, 77 | 0x1f423fcee22f9be0ULL, 0x659a4f06d21a1299ULL, 78 | 0xeaf2de5e82448912ULL, 0x902aae96b271006bULL, 79 | 0x74523609127ad31aULL, 0x0e8a46c1224f5a63ULL, 80 | 0x81e2d7997211c1e8ULL, 0xfb3aa75142244891ULL, 81 | 0xb46ad37a8a3b6595ULL, 0xceb2a3b2ba0eececULL, 82 | 0x41da32eaea507767ULL, 0x3b024222da65fe1eULL, 83 | 0xa2722586f2d042eeULL, 0xd8aa554ec2e5cb97ULL, 84 | 0x57c2c41692bb501cULL, 0x2d1ab4dea28ed965ULL, 85 | 0x624ac0f56a91f461ULL, 0x1892b03d5aa47d18ULL, 86 | 0x97fa21650afae693ULL, 0xed2251ad3acf6feaULL, 87 | 0x095ac9329ac4bc9bULL, 0x7382b9faaaf135e2ULL, 88 | 0xfcea28a2faafae69ULL, 0x8632586aca9a2710ULL, 89 | 0xc9622c4102850a14ULL, 0xb3ba5c8932b0836dULL, 90 | 0x3cd2cdd162ee18e6ULL, 0x460abd1952db919fULL, 91 | 0x256b24ca6b12f26dULL, 0x5fb354025b277b14ULL, 92 | 0xd0dbc55a0b79e09fULL, 0xaa03b5923b4c69e6ULL, 93 | 0xe553c1b9f35344e2ULL, 0x9f8bb171c366cd9bULL, 94 | 0x10e3202993385610ULL, 0x6a3b50e1a30ddf69ULL, 95 | 0x8e43c87e03060c18ULL, 0xf49bb8b633338561ULL, 96 | 0x7bf329ee636d1eeaULL, 0x012b592653589793ULL, 97 | 0x4e7b2d0d9b47ba97ULL, 0x34a35dc5ab7233eeULL, 98 | 0xbbcbcc9dfb2ca865ULL, 0xc113bc55cb19211cULL, 99 | 0x5863dbf1e3ac9decULL, 0x22bbab39d3991495ULL, 100 | 0xadd33a6183c78f1eULL, 0xd70b4aa9b3f20667ULL, 101 | 0x985b3e827bed2b63ULL, 0xe2834e4a4bd8a21aULL, 102 | 0x6debdf121b863991ULL, 0x1733afda2bb3b0e8ULL, 103 | 0xf34b37458bb86399ULL, 0x8993478dbb8deae0ULL, 104 | 0x06fbd6d5ebd3716bULL, 0x7c23a61ddbe6f812ULL, 105 | 0x3373d23613f9d516ULL, 0x49aba2fe23cc5c6fULL, 106 | 0xc6c333a67392c7e4ULL, 0xbc1b436e43a74e9dULL, 107 | 0x95ac9329ac4bc9b5ULL, 0xef74e3e19c7e40ccULL, 108 | 0x601c72b9cc20db47ULL, 0x1ac40271fc15523eULL, 109 | 0x5594765a340a7f3aULL, 0x2f4c0692043ff643ULL, 110 | 0xa02497ca54616dc8ULL, 0xdafce7026454e4b1ULL, 111 | 0x3e847f9dc45f37c0ULL, 0x445c0f55f46abeb9ULL, 112 | 0xcb349e0da4342532ULL, 0xb1eceec59401ac4bULL, 113 | 0xfebc9aee5c1e814fULL, 0x8464ea266c2b0836ULL, 114 | 0x0b0c7b7e3c7593bdULL, 0x71d40bb60c401ac4ULL, 115 | 0xe8a46c1224f5a634ULL, 0x927c1cda14c02f4dULL, 116 | 0x1d148d82449eb4c6ULL, 0x67ccfd4a74ab3dbfULL, 117 | 0x289c8961bcb410bbULL, 0x5244f9a98c8199c2ULL, 118 | 0xdd2c68f1dcdf0249ULL, 0xa7f41839ecea8b30ULL, 119 | 0x438c80a64ce15841ULL, 0x3954f06e7cd4d138ULL, 120 | 0xb63c61362c8a4ab3ULL, 0xcce411fe1cbfc3caULL, 121 | 0x83b465d5d4a0eeceULL, 0xf96c151de49567b7ULL, 122 | 0x76048445b4cbfc3cULL, 0x0cdcf48d84fe7545ULL, 123 | 0x6fbd6d5ebd3716b7ULL, 0x15651d968d029fceULL, 124 | 0x9a0d8ccedd5c0445ULL, 0xe0d5fc06ed698d3cULL, 125 | 0xaf85882d2576a038ULL, 0xd55df8e515432941ULL, 126 | 0x5a3569bd451db2caULL, 0x20ed197575283bb3ULL, 127 | 0xc49581ead523e8c2ULL, 0xbe4df122e51661bbULL, 128 | 0x3125607ab548fa30ULL, 0x4bfd10b2857d7349ULL, 129 | 0x04ad64994d625e4dULL, 0x7e7514517d57d734ULL, 130 | 0xf11d85092d094cbfULL, 0x8bc5f5c11d3cc5c6ULL, 131 | 0x12b5926535897936ULL, 0x686de2ad05bcf04fULL, 132 | 0xe70573f555e26bc4ULL, 0x9ddd033d65d7e2bdULL, 133 | 0xd28d7716adc8cfb9ULL, 0xa85507de9dfd46c0ULL, 134 | 0x273d9686cda3dd4bULL, 0x5de5e64efd965432ULL, 135 | 0xb99d7ed15d9d8743ULL, 0xc3450e196da80e3aULL, 136 | 0x4c2d9f413df695b1ULL, 0x36f5ef890dc31cc8ULL, 137 | 0x79a59ba2c5dc31ccULL, 0x037deb6af5e9b8b5ULL, 138 | 0x8c157a32a5b7233eULL, 0xf6cd0afa9582aa47ULL, 139 | 0x4ad64994d625e4daULL, 0x300e395ce6106da3ULL, 140 | 0xbf66a804b64ef628ULL, 0xc5bed8cc867b7f51ULL, 141 | 0x8aeeace74e645255ULL, 0xf036dc2f7e51db2cULL, 142 | 0x7f5e4d772e0f40a7ULL, 0x05863dbf1e3ac9deULL, 143 | 0xe1fea520be311aafULL, 0x9b26d5e88e0493d6ULL, 144 | 0x144e44b0de5a085dULL, 0x6e963478ee6f8124ULL, 145 | 0x21c640532670ac20ULL, 0x5b1e309b16452559ULL, 146 | 0xd476a1c3461bbed2ULL, 0xaeaed10b762e37abULL, 147 | 0x37deb6af5e9b8b5bULL, 0x4d06c6676eae0222ULL, 148 | 0xc26e573f3ef099a9ULL, 0xb8b627f70ec510d0ULL, 149 | 0xf7e653dcc6da3dd4ULL, 0x8d3e2314f6efb4adULL, 150 | 0x0256b24ca6b12f26ULL, 0x788ec2849684a65fULL, 151 | 0x9cf65a1b368f752eULL, 0xe62e2ad306bafc57ULL, 152 | 0x6946bb8b56e467dcULL, 0x139ecb4366d1eea5ULL, 153 | 0x5ccebf68aecec3a1ULL, 0x2616cfa09efb4ad8ULL, 154 | 0xa97e5ef8cea5d153ULL, 0xd3a62e30fe90582aULL, 155 | 0xb0c7b7e3c7593bd8ULL, 0xca1fc72bf76cb2a1ULL, 156 | 0x45775673a732292aULL, 0x3faf26bb9707a053ULL, 157 | 0x70ff52905f188d57ULL, 0x0a2722586f2d042eULL, 158 | 0x854fb3003f739fa5ULL, 0xff97c3c80f4616dcULL, 159 | 0x1bef5b57af4dc5adULL, 0x61372b9f9f784cd4ULL, 160 | 0xee5fbac7cf26d75fULL, 0x9487ca0fff135e26ULL, 161 | 0xdbd7be24370c7322ULL, 0xa10fceec0739fa5bULL, 162 | 0x2e675fb4576761d0ULL, 0x54bf2f7c6752e8a9ULL, 163 | 0xcdcf48d84fe75459ULL, 0xb71738107fd2dd20ULL, 164 | 0x387fa9482f8c46abULL, 0x42a7d9801fb9cfd2ULL, 165 | 0x0df7adabd7a6e2d6ULL, 0x772fdd63e7936bafULL, 166 | 0xf8474c3bb7cdf024ULL, 0x829f3cf387f8795dULL, 167 | 0x66e7a46c27f3aa2cULL, 0x1c3fd4a417c62355ULL, 168 | 0x935745fc4798b8deULL, 0xe98f353477ad31a7ULL, 169 | 0xa6df411fbfb21ca3ULL, 0xdc0731d78f8795daULL, 170 | 0x536fa08fdfd90e51ULL, 0x29b7d047efec8728ULL, 171 | }; 172 | 173 | uint64_t crc64(const unsigned char *s, size_t l) { 174 | int j = 0; 175 | uint64_t crc = 0; 176 | 177 | for (j = 0; j < l; j++) { 178 | uint8_t byte = s[j]; 179 | crc = crc64_tab[(uint8_t)crc ^ byte] ^ (crc >> 8); 180 | } 181 | return crc; 182 | } 183 | 184 | /* Test main */ 185 | #ifdef TEST_MAIN 186 | #include 187 | int main(void) { 188 | printf("e9c6d914c4b8d9ca == %016llx\n", 189 | (unsigned long long) crc64("123456789",9)); 190 | return 0; 191 | } 192 | #endif 193 | -------------------------------------------------------------------------------- /crc/crc64.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRC_CRC64_H 2 | #define _CRC_CRC64_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif /* __cplusplus */ 7 | 8 | #include 9 | #include 10 | 11 | uint64_t crc64(const unsigned char *s, size_t l); 12 | 13 | #ifdef __cplusplus 14 | } 15 | #endif /* __cplusplus */ 16 | #endif 17 | -------------------------------------------------------------------------------- /crc/crc8.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** The crc32 is licensed under the Apache License, Version 2.0, and a copy of the license is included in this file. 3 | ** 4 | **Author:Wang Yaofu voipman@qq.com 5 | **Description: The source file of class crc8. 6 | ** following parameters: 7 | ** 8 | ** Width : 8 bit 9 | ** Poly : 0x31 (That is actually x^8 + x^5 + x^4 + 1) 10 | ** Initialization : 00 11 | ** Reflect Input byte : False 12 | ** Reflect Output CRC : False 13 | ** Xor constant to output CRC : 00 14 | ** Output for "123456789" : a2 15 | */ 16 | 17 | #include "crc8.h" 18 | 19 | 20 | static const uint8_t crc8tab_lsb[256] = { 21 | 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 22 | 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c, 23 | 0x23, 0x27, 0x2b, 0x2f, 0x33, 0x37, 0x3b, 0x3f, 24 | 0x03, 0x07, 0x0b, 0x0f, 0x13, 0x17, 0x1b, 0x1f, 25 | 0x25, 0x21, 0x2d, 0x29, 0x35, 0x31, 0x3d, 0x39, 26 | 0x05, 0x01, 0x0d, 0x09, 0x15, 0x11, 0x1d, 0x19, 27 | 0x06, 0x02, 0x0e, 0x0a, 0x16, 0x12, 0x1e, 0x1a, 28 | 0x26, 0x22, 0x2e, 0x2a, 0x36, 0x32, 0x3e, 0x3a, 29 | 0x29, 0x2d, 0x21, 0x25, 0x39, 0x3d, 0x31, 0x35, 30 | 0x09, 0x0d, 0x01, 0x05, 0x19, 0x1d, 0x11, 0x15, 31 | 0x0a, 0x0e, 0x02, 0x06, 0x1a, 0x1e, 0x12, 0x16, 32 | 0x2a, 0x2e, 0x22, 0x26, 0x3a, 0x3e, 0x32, 0x36, 33 | 0x0c, 0x08, 0x04, 0x00, 0x1c, 0x18, 0x14, 0x10, 34 | 0x2c, 0x28, 0x24, 0x20, 0x3c, 0x38, 0x34, 0x30, 35 | 0x2f, 0x2b, 0x27, 0x23, 0x3f, 0x3b, 0x37, 0x33, 36 | 0x0f, 0x0b, 0x07, 0x03, 0x1f, 0x1b, 0x17, 0x13, 37 | 0x31, 0x35, 0x39, 0x3d, 0x21, 0x25, 0x29, 0x2d, 38 | 0x11, 0x15, 0x19, 0x1d, 0x01, 0x05, 0x09, 0x0d, 39 | 0x12, 0x16, 0x1a, 0x1e, 0x02, 0x06, 0x0a, 0x0e, 40 | 0x32, 0x36, 0x3a, 0x3e, 0x22, 0x26, 0x2a, 0x2e, 41 | 0x14, 0x10, 0x1c, 0x18, 0x04, 0x00, 0x0c, 0x08, 42 | 0x34, 0x30, 0x3c, 0x38, 0x24, 0x20, 0x2c, 0x28, 43 | 0x37, 0x33, 0x3f, 0x3b, 0x27, 0x23, 0x2f, 0x2b, 44 | 0x17, 0x13, 0x1f, 0x1b, 0x07, 0x03, 0x0f, 0x0b, 45 | 0x18, 0x1c, 0x10, 0x14, 0x08, 0x0c, 0x00, 0x04, 46 | 0x38, 0x3c, 0x30, 0x34, 0x28, 0x2c, 0x20, 0x24, 47 | 0x3b, 0x3f, 0x33, 0x37, 0x2b, 0x2f, 0x23, 0x27, 48 | 0x1b, 0x1f, 0x13, 0x17, 0x0b, 0x0f, 0x03, 0x07, 49 | 0x3d, 0x39, 0x35, 0x31, 0x2d, 0x29, 0x25, 0x21, 50 | 0x1d, 0x19, 0x15, 0x11, 0x0d, 0x09, 0x05, 0x01, 51 | 0x1e, 0x1a, 0x16, 0x12, 0x0e, 0x0a, 0x06, 0x02 52 | }; 53 | 54 | static const uint8_t crc8tab_msb[256] = { 55 | 0x00, 0x31, 0x62, 0x53, 0xc4, 0xf5, 0xa6, 0x97, 56 | 0xb9, 0x88, 0xdb, 0xea, 0x7d, 0x4c, 0x1f, 0x2e, 57 | 0x43, 0x72, 0x21, 0x10, 0x87, 0xb6, 0xe5, 0xd4, 58 | 0xfa, 0xcb, 0x98, 0xa9, 0x3e, 0x0f, 0x5c, 0x6d, 59 | 0x86, 0xb7, 0xe4, 0xd5, 0x42, 0x73, 0x20, 0x11, 60 | 0x3f, 0x0e, 0x5d, 0x6c, 0xfb, 0xca, 0x99, 0xa8, 61 | 0xc5, 0xf4, 0xa7, 0x96, 0x01, 0x30, 0x63, 0x52, 62 | 0x7c, 0x4d, 0x1e, 0x2f, 0xb8, 0x89, 0xda, 0xeb, 63 | 0x3d, 0x0c, 0x5f, 0x6e, 0xf9, 0xc8, 0x9b, 0xaa, 64 | 0x84, 0xb5, 0xe6, 0xd7, 0x40, 0x71, 0x22, 0x13, 65 | 0x7e, 0x4f, 0x1c, 0x2d, 0xba, 0x8b, 0xd8, 0xe9, 66 | 0xc7, 0xf6, 0xa5, 0x94, 0x03, 0x32, 0x61, 0x50, 67 | 0xbb, 0x8a, 0xd9, 0xe8, 0x7f, 0x4e, 0x1d, 0x2c, 68 | 0x02, 0x33, 0x60, 0x51, 0xc6, 0xf7, 0xa4, 0x95, 69 | 0xf8, 0xc9, 0x9a, 0xab, 0x3c, 0x0d, 0x5e, 0x6f, 70 | 0x41, 0x70, 0x23, 0x12, 0x85, 0xb4, 0xe7, 0xd6, 71 | 0x7a, 0x4b, 0x18, 0x29, 0xbe, 0x8f, 0xdc, 0xed, 72 | 0xc3, 0xf2, 0xa1, 0x90, 0x07, 0x36, 0x65, 0x54, 73 | 0x39, 0x08, 0x5b, 0x6a, 0xfd, 0xcc, 0x9f, 0xae, 74 | 0x80, 0xb1, 0xe2, 0xd3, 0x44, 0x75, 0x26, 0x17, 75 | 0xfc, 0xcd, 0x9e, 0xaf, 0x38, 0x09, 0x5a, 0x6b, 76 | 0x45, 0x74, 0x27, 0x16, 0x81, 0xb0, 0xe3, 0xd2, 77 | 0xbf, 0x8e, 0xdd, 0xec, 0x7b, 0x4a, 0x19, 0x28, 78 | 0x06, 0x37, 0x64, 0x55, 0xc2, 0xf3, 0xa0, 0x91, 79 | 0x47, 0x76, 0x25, 0x14, 0x83, 0xb2, 0xe1, 0xd0, 80 | 0xfe, 0xcf, 0x9c, 0xad, 0x3a, 0x0b, 0x58, 0x69, 81 | 0x04, 0x35, 0x66, 0x57, 0xc0, 0xf1, 0xa2, 0x93, 82 | 0xbd, 0x8c, 0xdf, 0xee, 0x79, 0x48, 0x1b, 0x2a, 83 | 0xc1, 0xf0, 0xa3, 0x92, 0x05, 0x34, 0x67, 0x56, 84 | 0x78, 0x49, 0x1a, 0x2b, 0xbc, 0x8d, 0xde, 0xef, 85 | 0x82, 0xb3, 0xe0, 0xd1, 0x46, 0x77, 0x24, 0x15, 86 | 0x3b, 0x0a, 0x59, 0x68, 0xff, 0xce, 0x9d, 0xac 87 | }; 88 | 89 | // LSB-first 90 | uint8_t crc8_lsb(const unsigned char *buf, size_t len) { 91 | int counter; 92 | uint8_t crc = 0; 93 | for (counter = 0; counter < len; counter++) 94 | crc = crc8tab_lsb[crc ^ *buf++]; 95 | return crc; 96 | } 97 | 98 | // MSB-first 99 | uint8_t crc8_msb(const unsigned char *buf, size_t len) { 100 | int counter; 101 | uint8_t crc = 0; 102 | for (counter = 0; counter < len; counter++) 103 | crc = crc8tab_msb[crc ^ *buf++]; 104 | return crc; 105 | } 106 | -------------------------------------------------------------------------------- /crc/crc8.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRC_CRC8_H 2 | #define _CRC_CRC8_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif /* __cplusplus */ 7 | 8 | #include 9 | #include 10 | 11 | // LSB-first 12 | uint8_t crc8_lsb(const unsigned char *buf, size_t len); 13 | 14 | // MSB-first 15 | uint8_t crc8_msb(const unsigned char *buf, size_t len); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif /* __cplusplus */ 20 | #endif 21 | -------------------------------------------------------------------------------- /crc/crc_poly.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** The crc is licensed under the Apache License, Version 2.0, and a copy of the license is included in this file. 3 | ** 4 | **Author:Wang Yaofu voipman@qq.com 5 | **Description: The source file to calc crc poly. 6 | */ 7 | #include 8 | #include "crc_poly.h" 9 | 10 | // LSB-first 11 | uint8_t crc8_poly_lsb(uint8_t poly, uint8_t value) { 12 | uint8_t crc; 13 | uint8_t j; 14 | 15 | crc = value & 0xFF; 16 | for (j = 8; j > 0; --j) { 17 | if (crc & 1) { 18 | crc = (crc >> 1) ^ poly; 19 | } else { 20 | crc = crc >> 1; 21 | } 22 | } 23 | return crc; 24 | } 25 | 26 | uint8_t crc8_poly_msb(uint8_t poly, uint8_t value) { 27 | uint8_t crc; 28 | uint8_t j; 29 | uint8_t mask = 0x80; 30 | 31 | crc = value & 0xFF; 32 | for (j = 8; j > 0; --j) { 33 | if (crc & mask) { 34 | crc = (crc << 1) ^ poly; 35 | } else { 36 | crc = crc << 1; 37 | } 38 | } 39 | return crc; 40 | } 41 | 42 | // LSB-first 43 | uint16_t crc16_poly_lsb(uint16_t poly, uint16_t value) { 44 | uint16_t crc; 45 | uint16_t j; 46 | 47 | crc = value & 0xFF; 48 | for (j = 16; j > 0; --j) { 49 | if (crc & 1) { 50 | crc = (crc >> 1) ^ poly; 51 | } else { 52 | crc = crc >> 1; 53 | } 54 | } 55 | return crc; 56 | } 57 | 58 | // msb first 59 | uint16_t crc16_poly_msb(uint16_t poly, uint16_t value) { 60 | uint16_t crc; 61 | uint16_t j; 62 | 63 | crc = value & 0xFF; 64 | for (j = 16; j > 0; --j) { 65 | if (crc & 0x8000) { 66 | crc = (crc << 1) ^ poly; 67 | } else { 68 | crc = crc << 1; 69 | } 70 | } 71 | return crc; 72 | } 73 | 74 | // LSB-first 75 | uint32_t crc32_poly(uint32_t poly, uint16_t value) { 76 | uint32_t crc; 77 | uint16_t j; 78 | 79 | crc = value & 0xFF; 80 | for (j = 8; j > 0; --j) { 81 | if (crc & 1) { 82 | crc = (crc >> 1) ^ poly; 83 | } else { 84 | crc = crc >> 1; 85 | } 86 | } 87 | return crc; 88 | } 89 | 90 | // LSB-first 91 | uint64_t crc64_poly(uint64_t poly, uint16_t value) { 92 | uint64_t crc; 93 | uint16_t j; 94 | 95 | crc = value & 0xFF; 96 | for (j = 8; j > 0; --j) { 97 | if (crc & 1) { 98 | crc = (crc >> 1) ^ poly; 99 | } else { 100 | crc = (crc >> 1); 101 | } 102 | } 103 | return crc; 104 | } 105 | -------------------------------------------------------------------------------- /crc/crc_poly.h: -------------------------------------------------------------------------------- 1 | #ifndef _CRC_CRC_POLY_H 2 | #define _CRC_CRC_POLY_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif /* __cplusplus */ 7 | 8 | #include 9 | 10 | // LSB-first 11 | uint8_t crc8_poly_lsb(uint8_t poly, uint8_t value); 12 | 13 | // MSB-first 14 | uint8_t crc8_poly_msb(uint8_t poly, uint8_t value); 15 | 16 | // LSB-first 17 | uint16_t crc16_poly_lsb(uint16_t poly, uint16_t value); 18 | 19 | // MSB-first 20 | uint16_t crc16_poly_msb(uint16_t poly, uint16_t value); 21 | 22 | // LSB-first 23 | uint32_t crc32_poly(uint32_t poly, uint16_t value); 24 | 25 | // LSB-first 26 | uint64_t crc64_poly(uint64_t poly, uint16_t value); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif /* __cplusplus */ 31 | #endif // _CRC_CRC_POLY_H 32 | -------------------------------------------------------------------------------- /crc/crchash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ** The crc hash is licensed under the Apache License, Version 2.0, and a copy of the license is included in this file. 3 | ** 4 | **Author:Wang Yaofu voipman@qq.com 5 | **Description: The source file of class CrcHash. 6 | */ 7 | 8 | #include "crchash.h" 9 | #include "crc16.h" 10 | #include "crc32.h" 11 | #include "crc64.h" 12 | namespace common { 13 | uint16_t Hash16(const std::string& key) 14 | { 15 | return crc16(reinterpret_cast(key.c_str()), key.size()); 16 | } 17 | uint16_t Hash16(const unsigned char *cpKey, const size_t iKeyLen) 18 | { 19 | return crc16(cpKey, iKeyLen); 20 | } 21 | 22 | uint32_t Hash32(const std::string& key) 23 | { 24 | return crc32(reinterpret_cast(key.c_str()), key.size()); 25 | } 26 | uint32_t Hash32(const unsigned char *cpKey, const size_t iKeyLen) 27 | { 28 | return crc32(cpKey, iKeyLen); 29 | } 30 | 31 | uint64_t Hash64(const std::string& key) 32 | { 33 | return crc64(reinterpret_cast(key.c_str()), key.size()); 34 | } 35 | uint64_t Hash64(const unsigned char *cpKey, size_t iKeyLen) 36 | { 37 | return crc64(cpKey, iKeyLen); 38 | } 39 | } // namespace common 40 | -------------------------------------------------------------------------------- /crc/crchash.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** The crc hash is licensed under the Apache License, Version 2.0, and a copy of the license is included in this file. 3 | ** 4 | **Author:Wang Yaofu voipman@qq.com 5 | **Description: The header file of class CrcHash. 6 | */ 7 | 8 | #ifndef _COMMON_CRC_CRCHASH_H_ 9 | #define _COMMON_CRC_CRCHASH_H_ 10 | #include 11 | #include 12 | 13 | namespace common { 14 | // string => 0x0000-0xffff 15 | uint16_t Hash16(const std::string& key); 16 | uint16_t Hash16(const unsigned char *cpKey, size_t iKeyLen); 17 | 18 | // string => 0x00000000-0xffffffff 19 | uint32_t Hash32(const std::string& key); 20 | uint32_t Hash32(const unsigned char *cpKey, size_t iKeyLen); 21 | 22 | // string => 0x0000000000000000-0xffffffffffffffff 23 | uint64_t Hash64(const std::string& key); 24 | uint64_t Hash64(const unsigned char *cpKey, size_t iKeyLen); 25 | } // namespace common 26 | #endif // _COMMON_CRC_CRCHASH_H_ 27 | -------------------------------------------------------------------------------- /unit-test/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT = unittest 2 | 3 | CXX=gcc -g -std=c++11 4 | CC=gcc -g 5 | 6 | SHARED_FLAG = -fPIC -shared 7 | 8 | SRCS = . 9 | SRCS += ./ut 10 | SRCS += ../crc 11 | 12 | LIB = -lstdc++ -lpthread 13 | 14 | INC = -I. 15 | INC += -I.. 16 | 17 | OBJDIR = ./obj/ 18 | 19 | CPP_SRCS = $(foreach d,$(SRCS),$(wildcard $(d)/*.cpp)) 20 | C_SRCS = $(foreach d,$(SRCS),$(wildcard $(d)/*.c)) 21 | 22 | CPP_OBJS = $(patsubst %.cpp, %.o, $(CPP_SRCS)) 23 | C_OBJS = $(patsubst %.c, %.o, $(C_SRCS)) 24 | 25 | OBJS = $(CPP_OBJS) 26 | OBJS += $(C_OBJS) 27 | all : $(PROJECT) 28 | 29 | $(PROJECT) : $(OBJS) $(MODULE) 30 | $(CC) -o $@ $(OBJS) $(LIB) 31 | @echo "" 32 | @echo "+--------------------------------------------+" 33 | @echo "| Finish compilation unittest |" 34 | @echo "+--------------------------------------------+" 35 | @echo "| copyright(c)Wang Yaofu voipman@qq.com |" 36 | @echo "+--------------------------------------------+" 37 | 38 | clean: 39 | rm -rf *.o *.a *_unittest ../crc/*.o ut/test_harness.o 40 | 41 | install : 42 | test -d ../test || mkdir -p ../test 43 | cp unittest ../test 44 | 45 | %.o : %.cpp 46 | $(CXX) $(INC) -c $< -o $@ 47 | %.o : %.c 48 | $(CC) $(INC) -c $< -o $@ 49 | %.o : %.cc 50 | $(CC) $(INC) -c $< -o $@ 51 | -------------------------------------------------------------------------------- /unit-test/crc_test.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ** The crc unit test is licensed under the Apache License, Version 2.0, and a copy of the license is included in this file. 3 | ** 4 | **Author:Wang Yaofu 2018 voipman@qq.com 5 | **Description: The unit test file of crc. 6 | */ 7 | 8 | #include "ut/test_harness.h" 9 | #include "crc/crc8.h" 10 | #include "crc/crc16.h" 11 | #include "crc/crc32.h" 12 | #include "crc/crc64.h" 13 | #include "crc/crc_poly.h" 14 | #include 15 | 16 | TEST(CRC8Test, BasicTest) 17 | { 18 | const char* inData = "123456789"; 19 | uint8_t expect = 0xa2; 20 | EXPECT_EQ(crc8_msb(reinterpret_cast(inData), 9), expect); 21 | 22 | const char* data = "Hello World!!!"; 23 | expect = 0x68; 24 | EXPECT_EQ(crc8_msb(reinterpret_cast(data), strlen(data)), expect); 25 | 26 | expect = 0x2c; 27 | EXPECT_EQ(crc8_lsb(reinterpret_cast(data), strlen(data)), expect); 28 | 29 | const uint8_t buffer[] = {0xb0, 0, 0, 0, 0, 0, 0}; 30 | 31 | expect = 0x1a; 32 | EXPECT_EQ(crc8_lsb(buffer, sizeof(buffer)), expect); 33 | } 34 | 35 | TEST(CRC16Test, BasicTest) 36 | { 37 | const char* inData = "123456789"; 38 | uint16_t expect = 0x31C3; 39 | 40 | EXPECT_EQ(crc16(reinterpret_cast(inData), 9), expect); 41 | } 42 | 43 | TEST(CRC32Test, BasicTest) 44 | { 45 | const char* inData = "123456789"; 46 | uint32_t expect = 0xCBF43926; 47 | 48 | EXPECT_EQ(crc32(reinterpret_cast(inData), 9), expect); 49 | } 50 | 51 | TEST(CRC64Test, BasicTest) 52 | { 53 | const char* inData = "123456789"; 54 | 55 | uint64_t expect = 0xe9c6d914c4b8d9caL; 56 | EXPECT_EQ(crc64(reinterpret_cast(inData), 9), expect); 57 | } 58 | 59 | TEST(CRC8PolyTest, BasicTest) 60 | { 61 | uint8_t poly = 0x31; 62 | uint8_t crcTab[0xFF+1] = {0}; 63 | uint8_t expect = 0x00; 64 | EXPECT_EQ(crc8_poly_msb(poly, 0), expect); 65 | expect = 0x31; 66 | EXPECT_EQ(crc8_poly_msb(poly, 1), expect); 67 | expect = 0xac; 68 | EXPECT_EQ(crc8_poly_msb(poly, 0xFF), expect); 69 | 70 | /** 71 | for (int i = 0; i <= 0xff; ++i) { 72 | if (i % 8 == 0) { 73 | printf("\n"); 74 | } 75 | crcTab[i] = crc8_poly_lsb(poly, i); 76 | printf("0x%.2x, ", crcTab[i]); 77 | } 78 | */ 79 | } 80 | 81 | TEST(CRC16PolyTest, BasicTest) 82 | { 83 | // poly = x^16 + x^12 + x^5 + 1 = 0x1021 84 | uint16_t poly = 0x1021; 85 | uint16_t crcTab[0xFF+1] = {0}; 86 | uint16_t expect = 0x0000; 87 | EXPECT_EQ(crc16_poly_msb(poly, 0), expect); 88 | expect = 0x1021; 89 | EXPECT_EQ(crc16_poly_msb(poly, 1), expect); 90 | expect = 0x1ef0; 91 | EXPECT_EQ(crc16_poly_msb(poly, 0xFF), expect); 92 | } 93 | 94 | TEST(CRC32PolyTest, BasicTest) 95 | { 96 | uint32_t poly = 0xedb88320; 97 | uint32_t crcTab[0xFF+1] = {0}; 98 | uint32_t expect = 0x00000000L; 99 | EXPECT_EQ(crc32_poly(poly, 0), expect); 100 | expect = 0x77073096L; 101 | EXPECT_EQ(crc32_poly(poly, 1), expect); 102 | expect = 0x2d02ef8dL; 103 | EXPECT_EQ(crc32_poly(poly, 0xFF), expect); 104 | } 105 | 106 | -------------------------------------------------------------------------------- /unit-test/ut/test_harness.cpp: -------------------------------------------------------------------------------- 1 | #include "test_harness.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace common { 9 | namespace test { 10 | int errCount = 0; 11 | namespace { 12 | struct Test { 13 | const char* base; 14 | const char* name; 15 | void(*func)(); 16 | }; 17 | std::vector* tests; 18 | } 19 | 20 | bool RegisterTest(const char* base, const char* name, void(*func)()) { 21 | if (tests == NULL) { 22 | tests = new std::vector; 23 | } 24 | Test t; 25 | t.base = base; 26 | t.name = name; 27 | t.func = func; 28 | tests->push_back(t); 29 | return true; 30 | } 31 | 32 | int RunAllTests(const char* matcher) { 33 | int num = 0; 34 | if (tests != NULL) { 35 | for (size_t i = 0; i < tests->size(); i++) { 36 | const Test& t = (*tests)[i]; 37 | if (matcher != NULL) { 38 | std::string name = t.base; 39 | name.push_back('.'); 40 | name.append(t.name); 41 | if (strstr(name.c_str(), matcher) == NULL) { 42 | continue; 43 | } 44 | } 45 | fprintf(stderr, "\033[0;32m[ RUN ] ==== Test %s.%s\n", t.base, t.name); 46 | fprintf(stderr, "\033[0m"); 47 | (*t.func)(); 48 | ++num; 49 | } 50 | } 51 | fprintf(stderr, "\033[0;32m[ PASS ] ==== PASSED %d tests\n", num); 52 | fprintf(stderr, "\033[0;31m[ NOPASS ] ==== ERROR %d tests\n", errCount); 53 | fprintf(stderr, "\033[0m\n"); 54 | return 0; 55 | } 56 | 57 | std::string TmpDir() { 58 | return "/tmp"; 59 | } 60 | 61 | int RandomSeed() { 62 | return 301; 63 | } 64 | TestPerfomence::TestPerfomence() { 65 | startMs_ = NowMs(); 66 | } 67 | TestPerfomence::TestPerfomence(int size) { 68 | startMs_ = NowMs(); 69 | fprintf(stderr, 70 | "\033[0;32m[ RUN ] ==== start to run %lu cases.\n", 71 | size); 72 | } 73 | TestPerfomence::~TestPerfomence() { 74 | long endMs = NowMs(); 75 | fprintf(stderr, 76 | "\033[0;32m[ RUN ] ==== start at %lu, stop at %lu, cost:[%lu]\n", 77 | startMs_, endMs, endMs - startMs_); 78 | } 79 | long TestPerfomence::NowMs() { 80 | timespec timeNow{}; 81 | 82 | if (timespec_get(&timeNow, TIME_UTC) != TIME_UTC) 83 | { 84 | fputs("timespec_get failed!", stderr); 85 | return 0; 86 | } 87 | 88 | return static_cast(timeNow.tv_sec * 1000 + timeNow.tv_nsec / 1000); 89 | } 90 | 91 | } 92 | } // namespace common 93 | 94 | using namespace common::test; 95 | int main(int argc, char** argv) { 96 | common::test::RunAllTests(NULL); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /unit-test/ut/test_harness.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace common { 7 | namespace test { 8 | extern int errCount; 9 | // Run some of the tests registered by the TEST() macro. If the 10 | // environment variable "LEVELDB_TESTS" is not set, runs all tests. 11 | // Otherwise, runs only the tests whose name contains the value of 12 | // "LEVELDB_TESTS" as a substring. E.g., suppose the tests are: 13 | // TEST(Foo, Hello) { ... } 14 | // TEST(Foo, World) { ... } 15 | // LEVELDB_TESTS=Hello will run the first test 16 | // LEVELDB_TESTS=o will run both tests 17 | // LEVELDB_TESTS=Junk will run no tests 18 | // 19 | // Returns 0 if all tests pass. 20 | // Dies or returns a non-zero value if some test fails. 21 | extern int RunAllTests(const char* matcher); 22 | 23 | // Return the directory to use for temporary storage. 24 | extern std::string TmpDir(); 25 | 26 | // Return a randomization seed for this run. Typically returns the 27 | // same number on repeated invocations of this binary, but automated 28 | // runs may be able to vary the seed. 29 | extern int RandomSeed(); 30 | 31 | // An instance of Tester is allocated to hold temporary state during 32 | // the execution of an assertion. 33 | class Tester { 34 | private: 35 | bool ok_; 36 | const char* fname_; 37 | int line_; 38 | std::stringstream ss_; 39 | 40 | public: 41 | Tester(const char* f, int l) 42 | : ok_(true), fname_(f), line_(l) { 43 | } 44 | 45 | ~Tester() { 46 | if (!ok_) { 47 | fprintf(stderr, "\033[0;31m[ ERROR ] ==== %s:%d:%s\n", 48 | fname_, line_, ss_.str().c_str()); 49 | fprintf(stderr, "\033[0m"); 50 | errCount++; 51 | exit(1); 52 | } 53 | } 54 | 55 | Tester& Is(bool b, const char* msg) { 56 | if (!b) { 57 | ss_ << " Assertion failure " << msg; 58 | ok_ = false; 59 | } 60 | return *this; 61 | } 62 | 63 | #define BINARY_OP(name,op) \ 64 | template \ 65 | Tester& name(const X& x, const Y& y) { \ 66 | if (! (x op y)) { \ 67 | ss_ << " failed: Expect:" << std::hex << uint64_t {x} << (" " #op " ") << "Actual:" << std::hex << uint64_t {y}; \ 68 | ok_ = false; \ 69 | } \ 70 | return *this; \ 71 | } 72 | 73 | BINARY_OP(IsEq, ==) 74 | BINARY_OP(IsNe, !=) 75 | BINARY_OP(IsGe, >=) 76 | BINARY_OP(IsGt, >) 77 | BINARY_OP(IsLe, <=) 78 | BINARY_OP(IsLt, <) 79 | #undef BINARY_OP 80 | #define DOUBLE_OP(name,op) \ 81 | template \ 82 | Tester& name(const X& x, const Y& y) { \ 83 | if (! (x - y > -0.000001 && x-y <0.000001)) { \ 84 | ss_ << " failed: Expect:" << x << (" " #op " ") << "Actual:" << y; \ 85 | ok_ = false; \ 86 | } \ 87 | return *this; \ 88 | } 89 | DOUBLE_OP(IsDoubleEq, ==) 90 | #undef DOUBLE_OP 91 | 92 | // Attach the specified value to the error message if an error has occurred 93 | template 94 | Tester& operator<<(const V& value) { 95 | if (!ok_) { 96 | ss_ << " " << value; 97 | } 98 | return *this; 99 | } 100 | }; 101 | 102 | #define ASSERT_TRUE(c) ::common::test::Tester(__FILE__, __LINE__).Is((c), #c) 103 | #define ASSERT_FALSE(c) ::common::test::Tester(__FILE__, __LINE__).Is(!(c), #c) 104 | #define ASSERT_EQ(a,b) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(b)) 105 | #define ASSERT_NE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsNe((a),(b)) 106 | #define ASSERT_GE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsGe((a),(b)) 107 | #define ASSERT_GT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsGt((a),(b)) 108 | #define ASSERT_LE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLe((a),(b)) 109 | #define ASSERT_LT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLt((a),(b)) 110 | #define EXPECT_GT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLt((a),(b)) 111 | #define EXPECT_LT(a,b) ::common::test::Tester(__FILE__, __LINE__).IsLt((a),(b)) 112 | #define EXPECT_EQ(a,b) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(b)) 113 | #define EXPECT_NE(a,b) ::common::test::Tester(__FILE__, __LINE__).IsNe((a),(b)) 114 | #define EXPECT_DOUBLE_EQ(a,b) ::common::test::Tester(__FILE__, __LINE__).IsDoubleEq((a),(b)) 115 | #define EXPECT_TRUE(a) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(true)) 116 | #define EXPECT_FALSE(a) ::common::test::Tester(__FILE__, __LINE__).IsEq((a),(false)) 117 | #define EXPECT_THROW(a,exceptions) try {a;} catch(exceptions e) {EXPECT_TRUE(true);} catch(...) {EXPECT_TRUE(false);} 118 | #define EXPECT_ANY_THROW(a) try {a;} catch(...) {EXPECT_TRUE(true);} 119 | #define TCONCAT(a,b) TCONCAT1(a,b) 120 | #define TCONCAT1(a,b) a##b 121 | 122 | #define TEST(base,name) \ 123 | class TCONCAT(_Test_,base##name) : public ::common::test::TestBase { \ 124 | public: \ 125 | void _Run(); \ 126 | static void _RunIt() { \ 127 | TCONCAT(_Test_,base##name) t; \ 128 | t._Run(); \ 129 | } \ 130 | }; \ 131 | bool TCONCAT(_Test_ignored_,base##name) = \ 132 | ::common::test::RegisterTest(#base, #name, &TCONCAT(_Test_,base##name)::_RunIt); \ 133 | void TCONCAT(_Test_,base##name)::_Run() 134 | 135 | // Register the specified test. Typically not used directly, but 136 | // invoked via the macro expansion of TEST. 137 | extern bool RegisterTest(const char* base, const char* name, void (*func)()); 138 | 139 | class TestBase {}; 140 | 141 | class TestPerfomence { 142 | public: 143 | TestPerfomence(); 144 | TestPerfomence(int size); 145 | ~TestPerfomence(); 146 | long NowMs(); 147 | private: 148 | long startMs_; 149 | }; 150 | #define TEST_PERF(a,size) ::common::test::TestPerfomence a(size); 151 | } // namespace test 152 | } // namespace common 153 | --------------------------------------------------------------------------------