Datenintegrität prüfen
Verfasst: 05.02.2011 16:51
Tachchen,
ich bin gerade dabei meinen Programme die meine eigenen Dateiformate verwenden etwas mehr Sicherheit zu geben, indem ich vor dem "richtigen" Lesen, erst prüfen will, ob die Datei überhaupt "das richtige Format" hat.
Dazu hatte ich folgende Überlegung:
- Die Datei wir normal erstellt
- es wird eine CRC32 Prüfsumme der Datei gebildet
- diese wird nachträglich ans Ende der Datei geschrieben
Beim Lesen kann ich jedoch kein CRC32FileFingerprint() mehr nutzen, da ja in der Datei nun noch 4byte mehr sind, welche die Summe verändern.
Darum lese ich die Datei stückchenweise in ein Memory (beim erfassen bis 4 Bytes vor dem Ende) und bilde daraus eine Gesamtsumme, ist diese dann gleich den letzten 4 Bytes in denen die echte Summe steht, ist die Datei intackt.
Beispielcode, mit CRC32FileFingerprintEx() wo man angeben kann wie viel Bytes hinten weggelassen werden sollen:
(Es wird eine max. 200MB große Datei im Tempverzeichnis erstellt!)
Funktionieren tuts, meine Frage ist jetzt: Ob man das auch so macht ?
Oder gibt es da einen andere Weg ?
ich bin gerade dabei meinen Programme die meine eigenen Dateiformate verwenden etwas mehr Sicherheit zu geben, indem ich vor dem "richtigen" Lesen, erst prüfen will, ob die Datei überhaupt "das richtige Format" hat.
Dazu hatte ich folgende Überlegung:
- Die Datei wir normal erstellt
- es wird eine CRC32 Prüfsumme der Datei gebildet
- diese wird nachträglich ans Ende der Datei geschrieben
Beim Lesen kann ich jedoch kein CRC32FileFingerprint() mehr nutzen, da ja in der Datei nun noch 4byte mehr sind, welche die Summe verändern.
Darum lese ich die Datei stückchenweise in ein Memory (beim erfassen bis 4 Bytes vor dem Ende) und bilde daraus eine Gesamtsumme, ist diese dann gleich den letzten 4 Bytes in denen die echte Summe steht, ist die Datei intackt.
Beispielcode, mit CRC32FileFingerprintEx() wo man angeben kann wie viel Bytes hinten weggelassen werden sollen:
(Es wird eine max. 200MB große Datei im Tempverzeichnis erstellt!)
Code: Alles auswählen
Enumeration
#File
EndEnumeration
#FingerprintBuffer = 1024*1024 ; ( 1 MB )
Procedure.l CRC32FileFingerprintEx(FileName.s, Shift.q=0)
Protected Fingerprint.l
Protected File.i = ReadFile(#PB_Any, FileName)
If File
Protected *Buffer = AllocateMemory(#FingerprintBuffer)
Protected MaxLoc.q = Lof(File)+Shift-#FingerprintBuffer
While Loc(File) < MaxLoc
ReadData(File, *Buffer, #FingerprintBuffer)
Fingerprint = CRC32Fingerprint(*Buffer, #FingerprintBuffer, Fingerprint)
Wend
Protected Length = Lof(File)+Shift-Loc(File)
If Length
ReadData(File, *Buffer, Length)
Fingerprint = CRC32Fingerprint(*Buffer, Length, Fingerprint)
EndIf
CloseFile(File)
FreeMemory(*Buffer)
EndIf
ProcedureReturn Fingerprint
EndProcedure
; Schreiben
Define Length.i = Random(1024*1024)+1024*1024 ; ( 1MB - 2MB )
Define *Buffer = AllocateMemory(Length)
Define n.i
CreateFile(#File, GetTemporaryDirectory()+"Beispiel.txt")
For n = 1 To 100 ; ( 100MB - 200MB )
RandomData(*Buffer, Length)
WriteData(#File, *Buffer, Length)
Next
CloseFile(#File)
FreeMemory(*Buffer)
Define Fingerprint.l = CRC32FileFingerprint(GetTemporaryDirectory()+"Beispiel.txt")
Debug Fingerprint
OpenFile(#File, GetTemporaryDirectory()+"Beispiel.txt")
FileSeek(#File, Lof(#File))
WriteLong(#File, Fingerprint)
CloseFile(#File)
; Beschädigen
CompilerIf 0
OpenFile(#File, GetTemporaryDirectory()+"Beispiel.txt")
FileSeek(#File, Random(Lof(#File)))
WriteByte(#File, Random(255))
CloseFile(#File)
CompilerEndIf
; Lesen
Fingerprint = CRC32FileFingerprintEx(GetTemporaryDirectory()+"Beispiel.txt", -4)
Debug Fingerprint
ReadFile(#File, GetTemporaryDirectory()+"Beispiel.txt")
FileSeek(#File, Lof(#File)-4)
If ReadLong(#File) = Fingerprint
Debug "Datenintegrität: RICHTIG"
Else
Debug "Datenintegrität: FALSCH"
EndIf
CloseFile(#File)
Oder gibt es da einen andere Weg ?