Hallo zusammen,
ich beschäftige mich derzeit mit der CRC-Programmierung (in C) und
möchte gerne einen CRC32-Code programmieren. Der CRC16-Code ist soweit
fertig und funktioniert auch allerdings habe ich nun das Problem dass
der CRC32-Code falsche Werte anzeigt.
Bei der Erweiterung des funktionierenden CRC16-Codes auf CRC32 wird
eigentlich "nur" die Maske (für das MSB) und die Anzahl an Bits (die
verschoben werden) geändert.
Das heißt ich habe für die Maske statt 0x8000 (CRC16) nun 0x80000000
(CRC32).
Und statt einer Verschiebung um 8 Stellen, nun eine Verschiebung um 24
Stellen.
Die "LUT-32" funktioniert auch (zumindest stimmen die Hex-Werte dieser
Tabelle mit dem Online-Calculator überein daher vermute ich einen Fehler
in der Compute_CRC32() nur sehe ich es leider nicht..
Vielleicht hat jemand eine Idee?
Programmiert wird mit C und Eclipse (MinGW).
Der CRC Code wurde anhand eines Besipiels von folgendem Link erstellt:
http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
Die Ergebnisse werden geprüft mit:
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
CRC16-Code
1
#include<stdio.h>
2
#include<stdint.h>
3
#include<stdlib.h>
4
#include<string.h>
5
#include<inttypes.h>
6
7
8
staticunsignedshortCrcTable16[256];
9
staticunsignedshortcrc=0;
10
11
/*Look-Up Table erstellen */
12
voidCalculateTable_CRC16()
13
{
14
constunsignedshortgenerator=0x1021;
15
16
/* iterate over all possible input byte values 0 - 255 */
Tobias P. schrieb:> allerdings habe ich nun das Problem dass> der CRC32-Code falsche Werte anzeigt.
Dann sag doch mal, um was fuer eine Architektur es sich handelt. Denn je
nach Architektur kann long 32 oder 64 bit breit sein.
Mein Tipp, um Bugs auszuschliessen:
Nutze die Datentypen aus stdint.h, wenn du unsigned long als 32 bit
breit erwartest, nimm uint32_t. Diese Datentypen haben den Vorteil, dass
sie auf allen Platformen dieselbe Breite haben, d.h. du kannst den
Code entspannt auf einem x-bliebigen PC testen (z.B. mit Unittests),
damit die korrekte Funktion sicherstellen, und dann kannst du den Code
auch genauso auf einem uC nutzen. Mit int/long ist das nicht oder nur
umstaendlich moeglich.
Gerade bei Hash- und anderen kryptographischen Funktionen sollte man
diese Datentypen verwenden.
Und bevor hier wieder jemand schreit, dass das ja performancetechnisch
kacke ist:
Erstmal die korrekte Funktion sicherstellen! Danach kann man sich
immernoch um Performance kuemmern.
--- EDIT ---
1. Dein Code fuer CRC32 compiliert nicht. Da fehlt 'generator'.
2. Als 32 bit Applikation compiliert laeuft es immerhin, ob der Wert
richtig ist: keine Ahnung.
3. Als 64 bit Applikation gibt es einen Segfault.
Pass die Datentypen an und mach das Beispiel compilierfaehig!
Vielen Dank für die Antworten :-)
@Yalu: Genau. Und nach dem gegebenen Beispiel hatte ich die
CRC32-Berechnung umgesetzt. Dort steht ja ziemlich genau drin was
abgeändert werden muss, allerdings wird bei mir ein falscher Wert
erzeugt.
Wenn ich meinen Code ausführe mit folgenden Parametern:
Generatorpolynom: 0x4C11DB7
Message: 0xA1, 0xDE, 0x2B
Dann erzeugt mein Programm: d9f6d155
Richtig wäre (laut Online CRC32-Calculator): 94FCFF94
@bloody
Der Code wird auf Win7 64-bit ausgeführt.
Danke dir für den Tipp mit dem Datentyp. Tatsächlich möchte ich später
den Code auf einem Mikrocontroller übertragen (mit entsprechender
Anpassung) und da hatte ich mir zunächst um den Datentyp keine Gedanken
zu gemacht.
Beim "Copy/Paste" habe ich scheinbar den "generator ausgelassen.
Hier nochmal der angepasste (und ausführbare) Code.
----EDIT----
Ach verdammt..Jetzt hab ich den Fehler entdeckt.
Ich habe den Fehler an der falschen Stelle gesucht.
Tatsächlich habe ich beim überprüfen des CRC (per Online
CRC-Calculator) nicht darauf geachtet, dass oftmals die Einstellungen
"Input reflected / Result reflected" automatisch aktiviert sind und
somit natürlich ein anderes Ergebnis angezeigt wird. :-(
Ziemlicher Anfängerfehler aber dennoch danke für eure Mühen.
Den CRC32 Code hänge ich einfach nochmal an für die die es möglcherweise
mal benötigen.
Hey Tobias,
noch ein kleiner Verbesserungsvorschlag:
Gewoehen dir bitte an Funktionsprototypen hinzuschreiben.
Ich hab deinen Code mal so bearbeitet, wie ich es machen wuerde. Ueber
das const, usw. kann man streiten. Ist nur ein Vorschlag. Wenigstens
Funktionsprototypen solltest du dir aber angewoehnen :)
Kaj G. schrieb:> Gewoehen dir bitte an Funktionsprototypen hinzuschreiben.
Bei lokalen (static) Funktionen ist es üblich, die Definition vor den
Aufruf zu schreiben. Dann spart man sich die Deklaration.
Bei globalen Funktionen erfolgt die Deklaration im .h-File.