58

I'm looking for an implementation of CRC32 in C or C++ that is explicitly licensed as being no cost or public domain. The implementation here seems nice, but the only thing it says about the license is "source code", which isn't good enough. I'd prefer non LGPL so I don't have to fool around with a DLL (my app is closed source). I saw the adler32 implementation in zlib, but I'm checking small chunks of data, which adler is not good for.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
twk
  • 16,760
  • 23
  • 73
  • 97
  • Why do you think adler32 is no good for small chunks? – wnoise Nov 19 '08 at 19:16
  • 4
    http://www.zlib.net/zlib_tech.html "So if the Adler-32 is used on significantly less than about a kilobyte, it will be noticeably weaker than a CRC-32 on the same small block" – twk Nov 20 '08 at 00:56
  • 1
    You already accepted it, but if you want I can probably extract for you the one they use in the linux kernel pretty easily – Vinicius Kamakura Jul 28 '11 at 18:19
  • For future visitors, there is one implementation here http://create.stephan-brumme.com/crc32/#git1 and you can pull it git clone http://create.stephan-brumme.com/crc32/.git – enthusiasticgeek Nov 28 '14 at 16:03
  • Your licensing concern is based on false assumptions I think. Using LGPL libraries does *not* require you to open source your proprietary code, as LGPL is a weak copyleft license. GPL would, as it is strong copyleft, in which case you'd need a DLL based library to keep your source closed. Arduino core libraries are all LGPL, and you can write all the closed source, proprietary Arduino code in the world that you want to. – Gabriel Staples Aug 18 '16 at 16:23
  • I checked your link you provided by the way. At the top it says it uses the LGPL v3 license. This license is perfectly compatible with your closed source, proprietary code. You only have to give back source code for edits you make *on that LGPL library itself*, *not* on your proprietary code that uses that library. – Gabriel Staples Aug 18 '16 at 16:35
  • Now publicly listed as LGPL v3. I am the author of the source code at the specified link. The license was not previously clear but the code is open and free for use in your free or commercial applications with no strings attached. – NTDLS Jul 07 '20 at 17:54

9 Answers9

40

The SNIPPETS C Source Code Archive has a CRC32 implementation that is freely usable:

/* Copyright (C) 1986 Gary S. Brown.  You may use this program, or
   code or tables extracted from it, as desired without restriction.*/

(Unfortunately, c.snippets.org seems to have died. Fortunately, the Wayback Machine has it archived.)

In order to be able to compile the code, you'll need to add typedefs for BYTE as an unsigned 8-bit integer and DWORD as an unsigned 32-bit integer, along with the header files crc.h & sniptype.h.

The only critical item in the header is this macro (which could just as easily go in CRC_32.c itself:

#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
cjm
  • 61,471
  • 9
  • 126
  • 175
  • For input `[01,23,45,67,89,AB,CD,EF,01,23]` this implementation gives me **`0x27809EA7`**, rather than the **`0x3BF5092E`** that I get from online calculators, boost::crc and mIRC's scripting engine. At first glance I can't quite tell why. – Lightness Races in Orbit Sep 13 '12 at 18:09
  • 7
    @LightnessRacesinOrbit, you're doing it wrong. I get `0x3BF5092E`. My awesome psychic debugging skills tell me that `0x27809EA7` comes out if you initialize `oldcrc32` to `0` instead of `0xFFFFFFFF` like you're supposed to. – cjm Sep 13 '12 at 19:24
  • @cjm: You're absolutely right. Ta :) – Lightness Races in Orbit Sep 14 '12 at 12:24
  • 3
    Oh these snippets are nice! Sad that this website no longer exists. I put the CRC functions into a small project on github: https://github.com/panzi/CRC-and-checksum-functions I also made some tiny changes (use C99 `uint32_t` instead of `DWORD` etc. and fixed some warnings). Maybe one should rescue all these snippets into a github project? – panzi Dec 30 '12 at 06:10
  • 4
    I found it here: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.c – selbie Jan 29 '13 at 02:19
  • @selbie nice code. But note that you have to replace the `#include ` with `#include `. Probably the author forgot to replace some custom header before release — I checked, such a file isn't present in any of a packages. Also the line `p = buf;` need explicit casting `p = (uint8_t*)buf;` to not trigger a compiler error. – Hi-Angel Sep 23 '14 at 08:41
  • @cjm `unsigned 8-bit integer ` Probably you meant `unsigned char` ☺ – Hi-Angel Sep 23 '14 at 09:25
  • @cjm are you have any ideas what the «Success_» and «Error_» could be? It is undeclared, and even almighty Google have no ideas what is it could be. – Hi-Angel Sep 23 '14 at 09:43
  • 1
    @Hi-Angel, they're in [sniptype.h](http://web.archive.org/web/20080303103500/http://c.snippets.org/snip_lister.php?fname=sniptype.h), but you could just as well substitute any values suitable to your application. – cjm Sep 23 '14 at 14:19
  • 1
    I added the Snippets collection github: https://github.com/vonj/snippets – Prof. Falken Jun 01 '15 at 07:17
32

I am the author of the source code at the specified link. While the intention of the source code license is not clear (it will be later today), the code is in fact open and free for use in your free or commercial applications with no strings attached.

NTDLS
  • 4,757
  • 4
  • 44
  • 70
27

Use the Boost C++ libraries. There is a CRC included there and the license is good.

Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • 29
    Using boost makes sense if you're already using boost libraries. Otherwise it's like shooting with canon a bird - something you definitely can do, but does not makes any sense of doing it. – TarmoPikaro Dec 26 '15 at 21:07
  • 1
    @TarmoPikaro it's one header file, just copy it. – Zan Lynx Dec 26 '15 at 21:24
  • 13
    #include // for BOOST_STATIC_CONSTANT, etc. #include // for boost::uint_t Very first two lines drags along two more header files ? Endless swamp ? – TarmoPikaro Dec 26 '15 at 22:04
19

The crc code in zlib (http://zlib.net/) is among the fastest there is, and has a very liberal open source license.

And you should not use adler-32 except for special applications where speed is more important than error detection performance.

twk
  • 16,760
  • 23
  • 73
  • 97
Mark Adler
  • 101,978
  • 13
  • 118
  • 158
17

using zlib.h (http://refspecs.linuxbase.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/zlib-crc32-1.html):

#include <zlib.h>
unsigned long  crc = crc32(0L, Z_NULL, 0);
crc = crc32(crc, (const unsigned char*)data_address, data_len);
giuspen
  • 1,365
  • 3
  • 20
  • 33
5

pycrc is a Python script that generates C CRC code, with options to select the CRC size, algorithm and model.

It's released under the MIT licence. Is that acceptable for your purposes?

John Carter
  • 53,924
  • 26
  • 111
  • 144
5

The most simple and straightforward C/C++ implementation that I found is in a link at the bottom of this page:

Web Page: http://www.barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code

Code Download Link: https://barrgroup.com/code/crc.zip

It is a simple standalone implementation with one .h and one .c file. There is support for CRC32, CRC16 and CRC_CCITT thru the use of a define. Also, the code lets the user change parameter settings like the CRC polynomial, initial/final XOR value, and reflection options if you so desire.

The license is not explicitly defined ala LGPL or similar. However the site does say that they are placing the code in the public domain for any use. The actual code files also say this.

Hope it helps!

Martin M.
  • 186
  • 1
  • 9
4

The mhash library works pretty good for me. It's fast enough, supports multiple types of hashing (crc32, MD5, SHA-1, HAVAL, RIPEMD128, RIPEMD160, TIGER, GOST, etc.). To get CRC32 of a string you would do something like this:

 MHASH td = mhash_init(MHASH_CRC32);

 if (td == MHASH_FAILED) return -1; // handle failure

 mhash(td, s, strlen(s));

 unsigned int digest = 0; // crc32 will be stored here

 mhash_deinit(td, &digest);

 // do endian swap here if desired
stukelly
  • 4,257
  • 3
  • 37
  • 44
Nazar
  • 603
  • 5
  • 6
1

rurban's fork of SMHasher (the original SMHasher seems abandoned) has hardware CRC32 support. The changes were added before the initial commit, but try comparing the new CMakeLists.txt and the old one (which doesn't mention SSE at all).

The best option is probably Intel's zlib fork with PCLMULQDQ support described in this paper. This library also has the SSE 4.2 optimizations.

If you don't need portability and you're on Linux, you can use the kernel's implementation (which is hardware accelerated if available): https://stackoverflow.com/a/11156040/309483

Community
  • 1
  • 1
Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196