CRC
-
fricky: ok danke;) ist dann das ein anderes crc?
woher weiss ich ob ich crc16 oder crc32 brauche?
bye
-
Das solltest Du selbst bestimmen.
Ein CRC32 ist halt weitaus sicherer. Der arbeitet mit 32 Bit und die Möglichkeit einer falschen Checksumme besteht rechnerisch bei 1 zu 2^32 (1:4294967296)
Ein CRC16 ist halt etwas schneller und braucht nur 16 Bit. Den verwende ich gerne mal in nem externem Controller wenn nicht soviele Resourcen zur Verfügung habe. Die Datensicherheit sinkt allerdings auf 1 zu 2^16 (1:65536).
Das kann bei häufigen Fehlern, beispielsweise bei einer fehlerbehafteten Datenübertragung schon zu viel sein.
Babbage
-
justint schrieb:
woher weiss ich ob ich crc16 oder crc32 brauche?
kommt auf die paketgrösse an. bis zu 4096 bytes pro block kannst du crc16 nehmen. darüber hinaus steigt dann die anzahl möglicher nichterkannter fehler schnell an, so dass ein crc32 oder sowas her muss.
-
Optimized CRC-16 calculation. Polynomial: x^16 + x^15 + x^2 + 1 (0xa001) Initial value: 0xffff This CRC is normally used in disk-drive controllers. The following is the equivalent functionality written in C. uint16_t crc16_update(uint16_t crc, uint8_t a) { int i; crc ^= a; for (i = 0; i < 8; ++i) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } return crc; }
unsigned int var1 = 12; unsigned int var2 = 3; unsigned int var3 = 9; unsigned int crc = 0xffff; crc = crc16_update(crc, var1); crc = crc16_update(crc, var2); crc = crc16_update(crc, var3); cout << "crc: " << crc << endl;
darf man da unsigned int durchjagen? denk mal nicht wegen -> uint8_t a
was nun? das ist ja alles für uint8_t ausgelegt?
-
Bevor dur mir Verzweifelst;)
WORD GetCRC16( BYTE *pcBuf, // pointer to buffer int iSizeofBuf // number of bytes (without CRC) ){ WORD uiCRC= 0xFFFF; for(int i= 0; i< iSizeofBuf; i++, pcBuf++){ uiCRC=uiCRC ^ (WORD)(*(BYTE*)pcBuf); for (int k=1;k<=8;k++){ if (uiCRC% 2){ uiCRC= uiCRC / 2; uiCRC= uiCRC ^ 0xA001; } else uiCRC= uiCRC / 2; } } return uiCRC; }
Jetzt bekommst nen 16Bit CRC einer beliebig langen Byte Sequenz;)
unsigned int var1 = 12; unsigned int var2 = 3; unsigned int var3 = 9; //unsigned int crc=0; struct HUHU{ int a,b,c; } obj; crc= GetCRC16((BYTE*)&var1,siezof(var1)); crc= GetCRC16((BYTE*)&var2,siezof(var2)); crc= GetCRC16((BYTE*)&var3,siezof(var3)); crc= GetCRC16((BYTE*)&obj,siezof(HUHU));
-
thx! ist das auch erlaubt?
typedef struct { unsigned short Pos; unsigned char Flag1; unsigned char Flag2; unsigned char PaddingByte0; unsigned char PaddingByte1; unsigned short CheckSum; }SingleSaved; SingleSaved.Pos = 0; SingleSaved.Flag1 = false; SingleSaved.Flag2 = true; SingleSaved.CheckSum = GetCRC16((char*)&SingleSaved, sizeof(SingleSaved)-sizeof(SingleSaved.CheckSum));
-
klar, würde aber ne funktion schreiben:
void UpdateCRC(SingleSaved *p){ p->CheckSum= GetCRC16((BYTE*)p, sizeof(SingleSaved)-sizeof(SingleSaved.CheckSum)); } struct SingleSaved obj; obj.Pos=... . . . UpdateCRC(&obj);
-
kann man UpdateCRC generisch machen?
-
du meinst das du jeden Typ mit ner CRC verstehen kannst? so einfach geht das nich..dazu müsstest du jedem Typ am ende 2 bytes verpassen wor die CRC rein kommt.
evtl. so
typdef unsigned short CRC_DAT; typedef struct{ char ac[20]; CRC_DAT; } TYPE_A; typedef struct{ int a,b,c; CRC_DAT; } TYPE_B; void UpdateCRC(void *p,unsigned int size){ WORD crc= GetCRC16((BYTE*)p,size - sizeof(CRC_DAT)); memcpy(p+(size - sizeof(CRC_DAT)), (BYTE*)&crc, 2); } struct TYPE_A o1; UpdateCRC(&o1,sizeof(TYPE_A)); struct TYPE_B o2; UpdateCRC(&o2,sizeof(TYPE_B));
-
BorisDieKlinge schrieb:
du meinst das du jeden Typ mit ner CRC verstehen kannst? so einfach geht das nich..dazu müsstest du jedem Typ am ende 2 bytes verpassen wor die CRC rein kommt.
quatsch. man macht sich einfach 'ne funktion, die einen void* und die anzahl der bytes bekommt und die dann den CRC als rückgabewert ausspuckt.
-
ja das macht ja (fast schon) die GetCRC16 funktion;)
siehe die posts oben, dann verstehst was er meint... er will die CRC jeder beliebigen stuktur mitgeben (wenn ich es richtig verstanden habe)