Skip to content

Instantly share code, notes, and snippets.

@timepp
Created February 16, 2017 11:39
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save timepp/1f678e200d9e0f2a043a9ec6b3690635 to your computer and use it in GitHub Desktop.
Save timepp/1f678e200d9e0f2a043a9ec6b3690635 to your computer and use it in GitHub Desktop.
simplest crc32 c++ implementation
#pragma once
#include <stdint.h>
struct crc32
{
static void generate_table(uint32_t(&table)[256])
{
uint32_t polynomial = 0xEDB88320;
for (uint32_t i = 0; i < 256; i++)
{
uint32_t c = i;
for (size_t j = 0; j < 8; j++)
{
if (c & 1) {
c = polynomial ^ (c >> 1);
}
else {
c >>= 1;
}
}
table[i] = c;
}
}
static uint32_t update(uint32_t (&table)[256], uint32_t initial, const void* buf, size_t len)
{
uint32_t c = initial ^ 0xFFFFFFFF;
const uint8_t* u = static_cast<const uint8_t*>(buf);
for (size_t i = 0; i < len; ++i)
{
c = table[(c ^ u[i]) & 0xFF] ^ (c >> 8);
}
return c ^ 0xFFFFFFFF;
}
};
// usage: the following code generates crc for 2 pieces of data
// uint32_t table[256];
// crc32::generate_table(table);
// uint32_t crc = crc32::update(table, 0, data_piece1, len1);
// crc = crc32::update(table, crc, data_piece2, len2);
// output(crc);
@DKGDKG
Copy link

DKGDKG commented Sep 27, 2018

1010101010

@berrak
Copy link

berrak commented Sep 19, 2022

Interesting, the second use is handy when crc32 structs in C++.

int main(){
	uint32_t table[256];
	crc32::generate_table(table);

	// Struct, for piece-by-piece, bytewise
	struct DataStruct {
		uint16_t data1;
		uint16_t data2;
		float mypi;
		uint32_t myclock;
		bool begun;
	};

	struct DataStruct Data = {42,17,3.14,123456789,false};
	char *ptr = (char *) &Data;
	uint16_t slen = sizeof(Data);
	printf("Size of Data struct is: %u\n", slen);                 // 16 bytes

	uint32_t CRC = 0;
	for (int cnt = 0; cnt < slen; cnt++) {
		CRC = crc32::update(table, CRC, ptr, 1);
		ptr++;
	}

	printf("Piece-wise crc32 of struct Data is: 0x%X \n", CRC);       // 0x6A8E18CE

}

@developergames2d
Copy link

With class:

#pragma once

#include <stdint.h>

struct CRC32_s
{
	void generate_table(uint32_t(&table)[256])
	{
		uint32_t polynomial = 0xEDB88320;
		for (uint32_t i = 0; i < 256; i++)
		{
			uint32_t c = i;
			for (size_t j = 0; j < 8; j++)
			{
				if (c & 1) {
					c = polynomial ^ (c >> 1);
				}
				else {
					c >>= 1;
				}
			}
			table[i] = c;
		}
	}

	uint32_t update(uint32_t(&table)[256], uint32_t initial, const void* buf, size_t len)
	{
		uint32_t c = initial ^ 0xFFFFFFFF;
		const uint8_t* u = static_cast<const uint8_t*>(buf);
		for (size_t i = 0; i < len; ++i)
		{
			c = table[(c ^ u[i]) & 0xFF] ^ (c >> 8);
		}
		return c ^ 0xFFFFFFFF;
	}
};

class CRC32
{
private:
	uint32_t table[256];
	CRC32_s crc32_s;
	uint32_t initial;
public:
	CRC32()
		: initial(0)
	{
		crc32_s.generate_table(table);
	}

	void Update(const unsigned __int8 * buf, size_t len)
	{
		initial = crc32_s.update(table, initial, (const void *)buf, len);
	}

	uint32_t GetValue() const
	{
		return initial;
	}
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment