Datenintegrität prüfen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Datenintegrität prüfen

Beitrag 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 ?
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Macros
Beiträge: 1361
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: Datenintegrität prüfen

Beitrag 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.
Bild
Benutzeravatar
w.pieperhoff
Beiträge: 41
Registriert: 15.05.2007 07:47
Wohnort: Westfalen

Re: Datenintegrität prüfen

Beitrag 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
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Datenintegrität prüfen

Beitrag 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?
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Datenintegrität prüfen

Beitrag 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.
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Datenintegrität prüfen

Beitrag 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.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
w.pieperhoff
Beiträge: 41
Registriert: 15.05.2007 07:47
Wohnort: Westfalen

Re: Datenintegrität prüfen

Beitrag 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
Zuletzt geändert von w.pieperhoff am 07.02.2011 12:47, insgesamt 2-mal geändert.
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Datenintegrität prüfen

Beitrag 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
Antworten