Hei Leute Ich versuche gerade eine C++ Awendung auf .Net umzuschreiben. Leider habe ich ein Problem mit dieser CRC Kalkulierung. Da sie etwas speziell ist, benötige ich Sie genau so wie im C++-File. Ich habe das ganze umgeschrieben nur irgendwie funktioniert das Ding nicht! Könnte mir vielleicht jemand sagen wo mein Fehler liegt. Ich seh' irgendwie den Wald vor lauter Bäumen nicht mehr.. Danke und Gruss Farin
> StreamReader sr = new StreamReader(file); http://msdn.microsoft.com/de-de/library/system.io.streamreader%28v=vs.80%29.aspx Implementiert einen TextReader, der Zeichen aus einem Bytestream in einer bestimmten Codierung liest. Das ist bestimmt nicht was du willst. Du solltest einen binary Reader verwenden. http://msdn.microsoft.com/de-de/library/system.io.binaryreader.aspx
Ok ich hab den StreamReader raus und den BinaryReader reingemacht.. Leider ist das Ergebnis noch immer nicht das Gleiche wie vom C++ File. Kannst du mir vielleicht noch einmal helfen? Danke und Gruss Farin
Wieso benutzt du in der C++-Version 'unsigned int' und in der C#-Version 'UInt64'?
Stimmt! Mein Fehler! Ich hab einen UInt32 draus gemacht. Erhalte aber noch immer das falsche Resultat...
Noch ein Fehler du benutzt in der C++-Variante 'unsigned short fileData' und in der C#-Variante 'byte'. Das muss deshalb eher so aussehen
1 | for (i = 0; i < size / 2; i +=2 ) |
2 | { |
3 | uiFileCRC |= ((ushort)fileBuffer[i] | ((ushort)fileBuffer[i + 1] << 8)); |
4 | ... |
5 | } |
Dies hat einen spezifischen Grund.. Ich weiss nicht was fread in der C++ Variante überhaupt ausliest. Er liest nach vorgabe unsigned char(8 bit) in ein unsigned short array(16 bit pro eintrag). Was macht der genau? Jeweils zwei chars pro short oder ein char pro short und dann shiften?
Nach Zeile 32 im C#-Programm fehlt
1 | size++; |
Es ist aber nicht korrekt, bei ungerader Blockgröße einfach 0xFF-Bytes einzufügen (das ist im C++-Programm schon falsch):
1 | if (size & 0x01) { |
2 | printf("Add one byte because odd file length\n\r"); |
3 | fileData[size] = 0xFF; |
4 | size++; |
5 | }
|
Das muss man vermutlich am Ende der Datei machen, aber ganz sicher nicht in der Mitte, weil sonst das CRC-Ergebnis davon abhängt, wie die die Datei beim Einlesen gestückelt wird. Bei gewöhnlichen Dateien tritt der Fehler wahrscheinlich nicht in Erscheinung, da die fread- bzw. Read-Funktion bei jedem Aufruf bis auf den letzten die gewünschte Anzahl von Bytes (2048) lesen wird und 2048 eine gerade Zahl ist. Ist die Datenquelle aber keine Datei, sondern bspw. eine serielle Schnittstelle, wird die Funktion ziemlich sicher bei gleichen Daten jedesmal ein anderes Ergebnis liefern. Ich verstehe aber sowieso nicht, warum im Originalprogramm die Daten 16-bit-weise verarbeitet werden. Durch die Art und Weise, wie dies gemacht wird, hängt das Ergebnis nämlich zusätzlich von der Endianess der verwendeten Plattform ab. Das Originalprogramm ist also ziemlicher Murks. Wenn du dazu kompatibel bleiben musst, kannst du diesen Murks übernehmen. Wenn du aber eine ordentliche CRC berechnen möchtest, solltest du dir eine andere Vorlage suchen.
Yalu X. schrieb: > Das Originalprogramm ist also ziemlicher Murks. Wenn du dazu kompatibel > bleiben musst, kannst du diesen Murks übernehmen. Wenn du aber eine > ordentliche CRC berechnen möchtest, solltest du dir eine andere Vorlage > suchen. Ergänzend: Es würde mich schon sehr wundern, wenn es in der umfangreichen .Net Bibliothek nicht schon eine fix&fertige CRC Berechnung gäbe.
Es gibt alles fixfertig. Aber das Problem ist. Dieser Algorythmus wurde auf einer integrierten Schaltung verwendet. Und um diese Schaltung noch verwenden zu können muss mein Tool diese spezielle CRC auch so berechnen können. Ich weiss es ist nervig und ich würde jeden anderen Weg bevorzugen aber es geht nunmal einfach nicht anders...
Ok Leute ich habs! Das Problem war effektiv das ushort/byte array in das ich die Daten kopiert habe. Ich habe das Kopieren der Daten nun folgendermassen realisiert und schon gehts perfekt wie ichs wollte:
1 | if ((rdr.BaseStream.Length - rdr.BaseStream.Position) >= 2048) |
2 | { |
3 | Buffer.BlockCopy(rdr.ReadBytes(2048), 0,fileBuffer, 0, 2048); |
4 | size = 2048; |
5 | } |
6 | else |
7 | { |
8 | int tempsize = (int)(rdr.BaseStream.Length - rdr.BaseStream.Position); |
9 | Buffer.BlockCopy(rdr.ReadBytes(2048), 0, fileBuffer, 0, tempsize); |
10 | size = tempsize; |
11 | } |
Danke an alle Helfer. Ihr seid super!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.