mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			111 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "globals.h"
 | |
| #include "bytes.h"
 | |
| #include "crc.h"
 | |
| 
 | |
| template <class T>
 | |
| T reflect(T bin, unsigned width = sizeof(T)*8)
 | |
| {
 | |
| 	T bout = 0;
 | |
| 	while (width--)
 | |
| 	{
 | |
| 		bout <<= 1;
 | |
| 		bout |= (bin & 1);
 | |
| 		bin >>= 1;
 | |
| 	}
 | |
| 	return bout;
 | |
| }
 | |
| 
 | |
| uint64_t generic_crc(const struct crcspec& spec, const Bytes& bytes)
 | |
| {
 | |
| 	uint64_t crc = spec.init;
 | |
| 	uint64_t top = 1LL << (spec.width-1);
 | |
| 	uint64_t mask = (top<<1) - 1;
 | |
| 
 | |
| 	for (uint8_t b : bytes)
 | |
| 	{
 | |
| 		if (spec.refin)
 | |
| 			b = reflect(b);
 | |
| 
 | |
| 		for (uint8_t i = 0x80; i != 0; i >>= 1)
 | |
| 		{
 | |
| 			uint64_t bit = crc & top;
 | |
| 			crc <<= 1;
 | |
| 			if (b & i)
 | |
| 				bit ^= top;
 | |
| 			if (bit)
 | |
| 				crc ^= spec.poly;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (spec.refout)
 | |
| 		crc = reflect(crc, spec.width);
 | |
| 	crc ^= spec.xorout;
 | |
| 	return crc & mask;
 | |
| }
 | |
| 
 | |
| uint16_t sumBytes(const Bytes& bytes)
 | |
| {
 | |
| 	ByteReader br(bytes);
 | |
| 
 | |
| 	uint16_t i = 0;
 | |
| 	while (!br.eof())
 | |
| 		i += br.read_8();
 | |
| 	return i;
 | |
| }
 | |
| 
 | |
| uint8_t xorBytes(const Bytes& bytes)
 | |
| {
 | |
| 	ByteReader br(bytes);
 | |
| 
 | |
| 	uint8_t i = 0;
 | |
| 	while (!br.eof())
 | |
| 		i ^= br.read_8();
 | |
| 	return i;
 | |
| }
 | |
| 
 | |
| uint16_t crc16(uint16_t poly, uint16_t crc, const Bytes& bytes)
 | |
| {
 | |
| 	ByteReader br(bytes);
 | |
| 
 | |
| 	while (!br.eof())
 | |
| 	{
 | |
| 		crc ^= br.read_8() << 8;
 | |
| 		for (int i=0; i<8; i++)
 | |
| 			crc = (crc & 0x8000) ? ((crc<<1)^poly) : (crc<<1);
 | |
| 	}
 | |
| 
 | |
| 	return crc;
 | |
| }
 | |
| 
 | |
| uint16_t crc16ref(uint16_t poly, uint16_t crc, const Bytes& bytes)
 | |
| {
 | |
| 	ByteReader br(bytes);
 | |
| 
 | |
| 	while (!br.eof())
 | |
| 	{
 | |
| 		crc ^= br.read_8();
 | |
| 		for (int i=0; i<8; i++)
 | |
| 			crc = (crc & 0x0001) ? ((crc>>1)^poly) : (crc>>1);
 | |
| 	}
 | |
| 
 | |
| 	return crc;
 | |
| }
 | |
| 
 | |
| /* Thanks to user202729 on StackOverflow for miraculously reverse engineering
 | |
|  * this. */
 | |
| uint32_t crcbrother(const Bytes& bytes)
 | |
| {
 | |
| 	ByteReader br(bytes);
 | |
| 
 | |
| 	uint32_t crc = br.read_8();
 | |
| 	while (!br.eof())
 | |
| 	{
 | |
| 		for (int i=0; i<8; i++)
 | |
| 			crc = (crc & 0x800000) ? ((crc<<1)^BROTHER_POLY) : (crc<<1);
 | |
| 		crc ^= br.read_8();
 | |
| 	}
 | |
| 
 | |
| 	return crc & 0xFFFFFF;
 | |
| }
 | |
| 
 |