Stránka 1 z 1

crc32 na crc16

Napsal: 17 pro 2012, 19:36
od DRAKE
Ahoj
Mám mikroprocesor od STMka, který umí hardwarově počítat 32 bitové CRC. Já potřebuji do své aplikace pouze 16 bitové. Je možné vzít z těch 32 bitů jenom prvních šestnáct a použít to a poté při ověřování zkontrolovat nulovost opět jenom těch prvních šestnácti bitů? Bude to fungovat jako spávné 16 bitové CRC?.

Děkuji za odpověď

Napsal: 17 pro 2012, 19:53
od Panda38
Rozhodně. Správné CRC má charakter náhodného čísla a tak každá jeho část je náhodným číslem a lze tedy použít k ověření. Jen bude větší šance na chybu a nebude to zřejmě normalizované.

Napsal: 17 pro 2012, 19:57
od Andrea
CRC má charakter náhodného čísla? Od kdy? 8O
CRC je zbytek po dělení konkrétního polynomu konkrétním polynomem a tudíž na něm není nic náhodného.

Napsal: 17 pro 2012, 20:02
od Panda38
Sice je to trochu off topic, tak se omlouvám DRAKE za vsuvku, ale zrovna jsem teď dělal CRC-CCITT XModem. Je to málo známý výpočet a je to škoda, má krátký kód a rychlost srovnatelnou s tabulkou (správnost výpočtu jsem ověřil srovnáním s tabulkovým výpočtem). Asm je sice pro AVR, ale třeba se to může někomu hodit.

Kód: Vybrat vše

/*-----------------------------------------------------------------------------
                        Calculate CRC-CCITT, 1 byte
-----------------------------------------------------------------------------*/

u16 Crc1(u16 crc, u8 data)
{

#ifdef USE_ASM

	asm (

	/* crc = (crc >> 8) | (crc << 8); */
	"mov	__tmp_reg__,%B0"	"\n\t"
	"mov	%B0,%A0"		"\n\t"

	/* crc ^= data; */
	"eor	__tmp_reg__,%1"		"\n\t"

	/* crc ^= (crc & 0xff) >> 4; */
	"mov	%A0,__tmp_reg__"	"\n\t"
	"swap	%A0"			"\n\t"
	"andi	%A0,0x0f"		"\n\t"
	"eor	__tmp_reg__,%A0"	"\n\t"

	/* crc ^= crc << 12; */
	"mov	%A0,__tmp_reg__"	"\n\t"
	"swap	%A0"			"\n\t"
	"andi	%A0,0xf0"		"\n\t"
	"eor	%B0,%A0"		"\n\t"

	/* crc ^= (crc & 0xff) << 5; */
	"mov	%A0,__tmp_reg__"	"\n\t"
	"swap	%A0"			"\n\t"
	"lsl	%A0"			"\n\t"
	"andi	%A0,0xe0"		"\n\t"
	"eor	%A0,__tmp_reg__"	"\n\t"
	"lsr	__tmp_reg__"		"\n\t"
	"lsr	__tmp_reg__"		"\n\t"
	"lsr	__tmp_reg__"		"\n\t"
	"eor	%B0,__tmp_reg__"	"\n\t"

	: "+r" (crc)
	: "r" (data)
	);

	return crc;

#else /* USE_ASM */

	crc = (crc >> 8) | (crc << 8);
	crc ^= data;
	crc ^= (crc & 0xff) >> 4;
	crc ^= crc << 12;
	crc ^= (crc & 0xff) << 5;
	return crc;

#endif /* USE_ASM */
}

/*-----------------------------------------------------------------------------
                      Calculate CRC-CCITT (XModem)
-----------------------------------------------------------------------------*/
/* Sample: 0xFC 0x05 0x4A -> 0x8048 */
#define CRC_INIT 0

u16 Crc(const void* buf, int len)
{
	u16 crc = CRC_INIT;
	const u8* s = (const u8*)buf;

	for (; len > 0; len--)
	{
		crc = Crc1(crc, *s++);
	}
	return crc;
}

Napsal: 17 pro 2012, 20:04
od Panda38
Andrea píše:CRC má charakter náhodného čísla? Od kdy? 8O
CRC je zbytek po dělení konkrétního polynomu konkrétním polynomem a tudíž na něm není nic náhodného.
Samozřejmě to není náhodné číslo! :)

Má vzhled náhodného čísla. Správné CRC vypadá při změně kontrolovaného obsahu tak, že se změní docela podstatně a na pohled jakoby náhodně. Jistě není moc dokonalé CRC, když při změně bitu 0 v datech se změní jen bit 0 v CRC.

Oříznutí 32 na 16 bitů by asi nebylo dobré např. u metody XOR + rotace (nebo u prostého součtu), protože tam se změna v datech projeví jen na 1 bitu, ale CRC-32 je dostatečně náhodný (pro Andreu proměnlivý :-) ) aby se to dalo oříznout.

Napsal: 17 pro 2012, 20:57
od procesor

Napsal: 29 led 2013, 17:58
od DRAKE
Jaká je vlastně detekční schopnost 16 bitového CRC s obecným polynomem.