Seite 1 von 1

Datenintegrität prüfen

Verfasst: 05.02.2011 16:51
von STARGÅTE
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!)

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)
Funktionieren tuts, meine Frage ist jetzt: Ob man das auch so macht ?
Oder gibt es da einen andere Weg ?

Re: Datenintegrität prüfen

Verfasst: 05.02.2011 20:32
von Macros
Hi,

Genau dafür ist CRC32 da, also wirds wohl auch so gemacht ;)

Das einzige Problem, dass mir auffällt:
Ich weiß nicht mit welchen Dateien du arbeitest, aber ab 256 MB, spätestens ab 512 und aufwärts würde ich die Datei in Sektionen unterteilen,
die je mit einer eigenen Checksumme gesichert sind.

Gelesen werden muss jedes Byte, und CRC32 ist sehr schnell, also kannst du ohne Qualitätsverlust nicht mehr viel rausholen.

Re: Datenintegrität prüfen

Verfasst: 05.02.2011 22:02
von w.pieperhoff
Hallo Stargate!
Ich würde die Datei in gleich großen Sektoren unterteilen, und dann die Sektoren_Checksummen anhängen.

Viel Spass

Re: Datenintegrität prüfen

Verfasst: 06.02.2011 01:08
von Thorium
w.pieperhoff hat geschrieben:Hallo Stargate!
Ich würde die Datei in gleich großen Sektoren unterteilen, und dann die Sektoren_Checksummen anhängen.

Viel Spass
Wieso das denn?

Re: Datenintegrität prüfen

Verfasst: 06.02.2011 03:24
von NicTheQuick
Mit mehreren Checksummen für einzelnen Teile ist natürlich die Kollisionswahrscheinlichkeit geringer. Aber dann könnte man auch gleich was höher-Bit-iges nehmen, also z.B. MD5 oder SHA1.

Re: Datenintegrität prüfen

Verfasst: 06.02.2011 11:10
von Thorium
NicTheQuick hat geschrieben:Mit mehreren Checksummen für einzelnen Teile ist natürlich die Kollisionswahrscheinlichkeit geringer. Aber dann könnte man auch gleich was höher-Bit-iges nehmen, also z.B. MD5 oder SHA1.
Ja.
Die Kollisionswahrscheinlichkeit ist sowieso extrem hoch. Ob man die nun halbiert oder viertelt, oder achtelt macht keinen wirklichen Unterschied. Macht nur das Dateiformat komplizierter.

Re: Datenintegrität prüfen

Verfasst: 07.02.2011 08:38
von w.pieperhoff
Hallo!
Mein Vorschlag zielte nur darauf hin, durch die Unterteilung erkennen zu können
an welcher Stelle des Codes eine Veränderung eingetreten ist. Um auch die kleinsten
Veränderungen Stellenmäßig zu erfassen.

Einen schönen Tag wünsche ich alle Lesern noch

Re: Datenintegrität prüfen

Verfasst: 07.02.2011 09:30
von Nino
Die Anforderungen an Integritätstests sind andere als diejenigen an Identitätstests (etwa digitale Unterschrift). CRC32 sollte hier wohl reichen, und ist schneller als MD5.

Grüße, Nino