2016-08-22 1 views
1

ich die Implementierung geändert haben gefunden here, eine Tabellenerzeugungsfunktion für eine CRC4 zu bauen, wie folgt:CRC4 Implementierung in C

#define bufferSize 16 
crc crcTable[bufferSize]; 
#define POLYNOMIAL 0x13 

void Init() 
{ 
    crc remainder; 

    for(int dividend = 0; dividend < bufferSize; ++dividend) 
    { 
      remainder = dividend; 
      for(uint8_t bit = 8; bit > 0; --bit) 
      { 
       if(remainder & 1) 
        remainder = (remainder >> 1)^POLYNOMIAL; 
       else 
        remainder = (remainder >> 1); 
      } 

      crcTable[dividend] = remainder; 
      printf("%hu\n", remainder); 
    } 
} 

Und dann berechnen Sie die CRC wie folgt aus:

uint8_t calc_crc4(uint8_t start_crc, uint8_t byte) 
{ 
    byte ^= start_crc; 
    start_crc = crcTable[byte]^(start_crc >> 8); 

    return start_crc; 
} 

Mit eine generierte crcTabelle von:

/* 
* Table based on Polynomial 0x13 
*/ 
uint8_t crcTable[tableSize] = { 
    0x00, 0x0E, 0x1C, 0x12, 
    0x1F, 0x11, 0x03, 0x0D, 
    0x19, 0x17, 0x05, 0x0B, 
    0x06, 0x08, 0x1A, 0x14 
}; 

Das Problem ist, dass wenn ich es gegen laufen eine ERF-Datei, keiner meiner generierten CRC-Werte sind gleich denen, die an das Ende eines ERF-Rahmens angehängt sind. Wenn ich Werte drucke, sieht es so aus, als ob der Aufruf an crcTable[byte] in der calc_crc4 Funktion fast immer den Wert 0x00 zurückgibt, aber ich verstehe das Konzept nicht gut genug, um zu wissen, ob dies der richtige Wert ist oder nicht. Das einzige, was mir einfällt, ist, dass es an der Indexposition von Byte nichts findet, also gibt es 0x00 zurück. Ich ging davon aus, dass es nur 16 Werte eines CRC4 geben kann, also müsste da etwas an diesem Ort sein.

+3

Was genau erwarten Sie 'start_crc >> 8' zu erreichen für' uint8_t start_crc'? – EOF

+0

'crcTable [Byte]' Adressieren Sie Speicher außerhalb der Array-Grenzen hier? Byte muss 0 - 15 sein. Wo durchlaufen Sie tatsächlich alle Bytes in einer Nachricht wie die Referenzimplementierung? – samgak

+0

'crc Rest; .... printf ("% hu \ n", Rest); 'macht wenig Sinn, wenn nicht hochgeladenes' crc' 'unsigned short' oder vielleicht' unsigned' ist. Post-Definition von 'CRC'. – chux

Antwort

1

Sie haben nicht die vollständige Definition des gewünschten CRC, und Ihr Versuch, die Implementierung auf vier Bits zu extrapolieren, weist viele Fehler auf.

Zunächst einmal müssen Sie mehr als das Polynom wissen. Sie müssen wissen, ob der CRC widergespiegelt wird, ob die Ausgabe auch reflektiert wird, wie der anfängliche Registerwert ist und ob die Ausgabe mit einem bestimmten Wert verknüpft ist oder nicht.

Zweitens, wenn Sie ein Byte zu einem Zeitpunkt verarbeiten, muss die Tabelle 256 Einträge haben, unabhängig von der Länge der CRC. Außerdem muss jeder Eintrag die Länge der CRC haben, in diesem Fall vier Bits, wobei Sie Einträge mit fünf haben. Außerdem müssen Sie den CRC am richtigen Ende des Bytes für die erste Exklusiv-oder vor der Tabelle Lookup setzen, oder verschieben Sie die Tabelle. Wie bereits angemerkt, ist ein Acht-Bit-Wert, der um acht Bits nach unten verschoben ist, gleich Null, so dass eine Exklusiv-Oder-Verknüpfung nichts bewirkt.

Eine tabellengesteuerte Implementierung eines Vier-Bit-CRC würde je nach Reflektion so etwas wie eines davon sein.

static unsigned char const table_byte[256] = { 
    0x90, 0xa0, 0xf0, 0xc0, 0x50, 0x60, 0x30, 0x00, 0x20, 0x10, 0x40, 0x70, 0xe0, 
    0xd0, 0x80, 0xb0, 0xc0, 0xf0, 0xa0, 0x90, 0x00, 0x30, 0x60, 0x50, 0x70, 0x40, 
    0x10, 0x20, 0xb0, 0x80, 0xd0, 0xe0, 0x30, 0x00, 0x50, 0x60, 0xf0, 0xc0, 0x90, 
    0xa0, 0x80, 0xb0, 0xe0, 0xd0, 0x40, 0x70, 0x20, 0x10, 0x60, 0x50, 0x00, 0x30, 
    0xa0, 0x90, 0xc0, 0xf0, 0xd0, 0xe0, 0xb0, 0x80, 0x10, 0x20, 0x70, 0x40, 0xe0, 
    0xd0, 0x80, 0xb0, 0x20, 0x10, 0x40, 0x70, 0x50, 0x60, 0x30, 0x00, 0x90, 0xa0, 
    0xf0, 0xc0, 0xb0, 0x80, 0xd0, 0xe0, 0x70, 0x40, 0x10, 0x20, 0x00, 0x30, 0x60, 
    0x50, 0xc0, 0xf0, 0xa0, 0x90, 0x40, 0x70, 0x20, 0x10, 0x80, 0xb0, 0xe0, 0xd0, 
    0xf0, 0xc0, 0x90, 0xa0, 0x30, 0x00, 0x50, 0x60, 0x10, 0x20, 0x70, 0x40, 0xd0, 
    0xe0, 0xb0, 0x80, 0xa0, 0x90, 0xc0, 0xf0, 0x60, 0x50, 0x00, 0x30, 0x70, 0x40, 
    0x10, 0x20, 0xb0, 0x80, 0xd0, 0xe0, 0xc0, 0xf0, 0xa0, 0x90, 0x00, 0x30, 0x60, 
    0x50, 0x20, 0x10, 0x40, 0x70, 0xe0, 0xd0, 0x80, 0xb0, 0x90, 0xa0, 0xf0, 0xc0, 
    0x50, 0x60, 0x30, 0x00, 0xd0, 0xe0, 0xb0, 0x80, 0x10, 0x20, 0x70, 0x40, 0x60, 
    0x50, 0x00, 0x30, 0xa0, 0x90, 0xc0, 0xf0, 0x80, 0xb0, 0xe0, 0xd0, 0x40, 0x70, 
    0x20, 0x10, 0x30, 0x00, 0x50, 0x60, 0xf0, 0xc0, 0x90, 0xa0, 0x00, 0x30, 0x60, 
    0x50, 0xc0, 0xf0, 0xa0, 0x90, 0xb0, 0x80, 0xd0, 0xe0, 0x70, 0x40, 0x10, 0x20, 
    0x50, 0x60, 0x30, 0x00, 0x90, 0xa0, 0xf0, 0xc0, 0xe0, 0xd0, 0x80, 0xb0, 0x20, 
    0x10, 0x40, 0x70, 0xa0, 0x90, 0xc0, 0xf0, 0x60, 0x50, 0x00, 0x30, 0x10, 0x20, 
    0x70, 0x40, 0xd0, 0xe0, 0xb0, 0x80, 0xf0, 0xc0, 0x90, 0xa0, 0x30, 0x00, 0x50, 
    0x60, 0x40, 0x70, 0x20, 0x10, 0x80, 0xb0, 0xe0, 0xd0}; 

unsigned crc4interlaken(unsigned crc, void const *data, size_t len) { 
    if (data == NULL) 
     return 0; 
    crc &= 0xf; 
    crc <<= 4; 
    while (len--) 
     crc = table_byte[crc^*(unsigned char const *)data++]; 
    crc >>= 4; 
    return crc; 
} 

oder

static unsigned char const table_byte[256] = { 
    0x0, 0x7, 0xe, 0x9, 0x5, 0x2, 0xb, 0xc, 0xa, 0xd, 0x4, 0x3, 0xf, 0x8, 0x1, 0x6, 
    0xd, 0xa, 0x3, 0x4, 0x8, 0xf, 0x6, 0x1, 0x7, 0x0, 0x9, 0xe, 0x2, 0x5, 0xc, 0xb, 
    0x3, 0x4, 0xd, 0xa, 0x6, 0x1, 0x8, 0xf, 0x9, 0xe, 0x7, 0x0, 0xc, 0xb, 0x2, 0x5, 
    0xe, 0x9, 0x0, 0x7, 0xb, 0xc, 0x5, 0x2, 0x4, 0x3, 0xa, 0xd, 0x1, 0x6, 0xf, 0x8, 
    0x6, 0x1, 0x8, 0xf, 0x3, 0x4, 0xd, 0xa, 0xc, 0xb, 0x2, 0x5, 0x9, 0xe, 0x7, 0x0, 
    0xb, 0xc, 0x5, 0x2, 0xe, 0x9, 0x0, 0x7, 0x1, 0x6, 0xf, 0x8, 0x4, 0x3, 0xa, 0xd, 
    0x5, 0x2, 0xb, 0xc, 0x0, 0x7, 0xe, 0x9, 0xf, 0x8, 0x1, 0x6, 0xa, 0xd, 0x4, 0x3, 
    0x8, 0xf, 0x6, 0x1, 0xd, 0xa, 0x3, 0x4, 0x2, 0x5, 0xc, 0xb, 0x7, 0x0, 0x9, 0xe, 
    0xc, 0xb, 0x2, 0x5, 0x9, 0xe, 0x7, 0x0, 0x6, 0x1, 0x8, 0xf, 0x3, 0x4, 0xd, 0xa, 
    0x1, 0x6, 0xf, 0x8, 0x4, 0x3, 0xa, 0xd, 0xb, 0xc, 0x5, 0x2, 0xe, 0x9, 0x0, 0x7, 
    0xf, 0x8, 0x1, 0x6, 0xa, 0xd, 0x4, 0x3, 0x5, 0x2, 0xb, 0xc, 0x0, 0x7, 0xe, 0x9, 
    0x2, 0x5, 0xc, 0xb, 0x7, 0x0, 0x9, 0xe, 0x8, 0xf, 0x6, 0x1, 0xd, 0xa, 0x3, 0x4, 
    0xa, 0xd, 0x4, 0x3, 0xf, 0x8, 0x1, 0x6, 0x0, 0x7, 0xe, 0x9, 0x5, 0x2, 0xb, 0xc, 
    0x7, 0x0, 0x9, 0xe, 0x2, 0x5, 0xc, 0xb, 0xd, 0xa, 0x3, 0x4, 0x8, 0xf, 0x6, 0x1, 
    0x9, 0xe, 0x7, 0x0, 0xc, 0xb, 0x2, 0x5, 0x3, 0x4, 0xd, 0xa, 0x6, 0x1, 0x8, 0xf, 
    0x4, 0x3, 0xa, 0xd, 0x1, 0x6, 0xf, 0x8, 0xe, 0x9, 0x0, 0x7, 0xb, 0xc, 0x5, 0x2}; 


unsigned crc4itu(unsigned crc, void const *data, size_t len) { 
    if (data == NULL) 
     return 0; 
    crc &= 0xf; 
    while (len--) 
     crc = table_byte[crc^*(unsigned char const *)data++]; 
    return crc; 
} 

Dieser Code und Tabellen wurden von my crcany code erzeugt. Diese beiden CRCs sind in Greg Cook's catalog definiert, wobei diese beiden 4-Bit-CRC-Definitionen sind:

width=4 poly=0x3 init=0xf refin=false refout=false xorout=0xf check=0xb name="CRC-4/INTERLAKEN" 
width=4 poly=0x3 init=0x0 refin=true refout=true xorout=0x0 check=0x7 name="CRC-4/ITU" 
+0

Ist das 'size_t len'-Argument die Länge von' data' in Bytes?Danke, übrigens – Aginor

+0

Ja ............ –

+0

Können Sie mir zeigen, wie Sie die Tabelle (n) erzeugten? – Aginor