CRC



  • nw. auch unsigned char, du errechnet ja ne checksume einer bytesquenz... das ergebniss ist bzw. der rückgabewert ist unterschiedlich groß



  • hm

    ich will daraus die checksumme berechnen:
    tInt16u geschwindigkeit;
    tInt16u offset;
    tInt8u bewegung;
    tInt8u halten;

    dann muss der input min unsigned int sein, ist das nicht ok?

    bye



  • //DIE CRC FUNKTIOM
    unsigned long crc32(unsigned char *buf, int len)
    {
            unsigned char *p;
            unsigned long  crc;
    
            if (!crc32_table[1])    /* if not already done, */
                    init_crc32();   /* build table */
            crc = 0xffffffff;       /* preload shift register, per CRC-32 spec */
            for (p = buf; len > 0; ++p, --len)
                    crc = (crc << 8) ^ crc32_table[(crc >> 24) ^ *p];
            return ~crc;            /* transmit complement, per CRC-32 spec */
    }
    
    //DEINE DATEN
    struct typedef{
    
    tInt16u geschwindigkeit;
    tInt16u offset;
    tInt8u bewegung;
    tInt8u halten;
    
    } DATA;
    
    //Daten anlegen
    DATA x;
    
    //CRC berechnen
    unsigned long myCRC= crc32((unsigned char*)&x, sizeof(x));
    


  • so gehts natürlich auch!

    kann man auch ne crc table verwenden die kleiner ist als 256? wär fein!



  • du kansnt auch ne CRC funktion ohne Table verwenden. Die ist halt bischen langsamer. Aber wenn dein code nicht zeitkritisch ist, ists egal. die version mit dem look-up table ist nur performancetechnisch relevant.

    google mal



  • justint schrieb:

    kann man auch ne crc table verwenden die kleiner ist als 256? wär fein!

    klar, schau dir's dritte posting dieses threads an.
    🙂



  • 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)


Anmelden zum Antworten