Systemvoraussetzung
- Linux
- Windows
- PHP 4 >= 4.3.0
- PHP 5
Datei(en)
crc.php
Problem
Stellen Sie sich folgendes Szenario vor: Sie erstellen täglich ein Backup Ihrer
Datenbank und speichern die Backupdatei auf einen entfernten Backup-Server.
Dieser Vorgang passiert täglich und automatisch, sodass Sie dem Backup
ohne weiteres vertrauen und es jederzeit wieder in Ihre Datenbank einspielen
würden.
Sicherlich kennen Sie das Sprichwort „Vertrauen ist gut, Kontrolle ist besser“,
das Sie auch hier niemals vergessen sollten. Die Backupdatei mag vielleicht
beim Erstellen noch in Ordnung gewesen sein, kann aber eventuell beim
Übertragen auf dem Backup-Server
Schaden genommen haben. Außerdem
kann es passieren, dass beim Download vom Backup-Server
zu Ihrem Server
irgendetwas passiert ist, und die Datei nicht vollständig übertragen wurde.
Die Datei könnte auch manipuliert sein, aber davon gehen wir erst einmal nicht
aus. Dies würde auch durch die zyklische Redundanzprüfung nicht einwandfrei
gelöst werden können – dafür benötigen Sie kryptografische Hash-Funktionen
wie z. B. md5().
Lösung
Die Lösung kann hier nur eine zyklische Redundanzprüfung (CRC) sein. Dabei
handelt es sich um ein Verfahren zur Bestimmung eines Prüfwerts für Daten,
um Fehler z. B. bei einer Übertragung zum oder vom Backup-Server
erkennen
zu können. Wie gehen in unserem Fall davon aus, dass die Datei nicht von
einer anderen Person manipuliert wurde, sondern beschränken uns auf eine
beschädigte Datei.
Das Beispiel erstellt für jede zu prüfende Datei eine sfv-Datei.
Inhalt der sfv-Datei
; Erstellt von SELFPHP CRC
; 02.04.2006 19:00:55
;
pecl5.1.2Win32.zip 4353f886 |
In unserem Beispiel wurde die Prüfsumme wie folgt erstellt:
Zu prüfende Datei: pecl5.1.2Win32.
zip
CRC-Prüfsumme:
4353f886
Die ersten drei Zeilen sind nur Kommentarzeilen, die beinhalten, wer die Datei
erstellt hat und wann sie erstellt wurde. Die vierte Zeile ist das eigentliche
Kernstück der Datei. Zum einen beinhaltet sie den Dateinamen unserer zu prüfenden
Datei, zum anderen die Prüfsumme als hexadezimale Repräsentation.
Beide Werte sind lediglich mit einem Leerzeichen voneinander getrennt.
Diese Datei ist so aufgebaut, dass sie z. B. auch mit dem Programm Total
Commander oder DF CrcSfv zur Prüfung Ihrer Dateien genutzt werden kann.
function createCRC($file)
@param string $file
@return bool
Die Funktion createCRC() erwartet als einzigen Parameter den Dateinamen
für die Prüfsummenerstellung. Dies könnte z. B. eine Backupdatei sein. Im
ersten Schritt wird überprüft (34), ob die angegebene Datei existiert. Sollte die
Prüfung erfolgreich sein, so wird der komplette Dateiinhalt in eine Variable gelesen
(36). Sollte Ihre PHP-Version
die Funktion file_get_contents() nicht
unterstützen, können Sie an dieser Stelle die Datei auch mit fread() einlesen.
Die erste Wahl sollte aber immer file_get_contents() sein, da gerade bei
sehr großen Dateien der Performancegewinn enorm ist. Aus der zuvor eingelesenen
Datei erstellen wir jetzt mit crc32() die Prüfsumme (38) und speichern
den Wert mittels dechex() (Dezimal zu Hexadezimal) als hexadezimale Repräsentation
in unsere Variable $crc (38).
Jetzt müssen wir lediglich den Inhalt unserer sfv-Datei
aufbauen (40-43).
Wichtig
ist hierbei, dass wir nur den Dateinamen (43) in die sfv-Datei
speichern.
Daher extrahieren wir mit basename() den Dateinamen aus unserem eventuellen
Pfad. Getrennt von einem Leerzeichen wird unsere Prüfsumme in
hexadezimaler Darstellung mit in die Datei gespeichert. Zum Schluss wird eine
neue sfv-Datei
erstellt (45-47),
die als Dateinamen unseren ursprünglichen Dateinamen der Backupdatei hat und als Dateiendung sfv enthält.
033: 034: 035: 036: 037: 038: 039: 040: 041: 042: 043: 044: 045: 046: 047: 048: 049: 050: 051: 052: 053: 054: 055: |
function createCRC($file)
{
if(file_exists($file)) {
$content = file_get_contents($file);
$crc = dechex(crc32($content)); $crcText .= "; Erstellt von SELFPHP CRC\n"; $crcText .= "; " . date("d.m.Y H:i:s") . "\n"; $crcText .= ";\n"; $crcText .= basename($file) . " " . $crc . "\n";
$handle = fopen ($file.".sfv", "w"); fputs ($handle, $crcText); fclose ($handle); return true; } return false; }
|
Beispiel 12.4: crc.php
function checkCRC($file)
@param string $file
@return bool
Die Function checkCRC() erwartet als einzigen Parameter den Dateinamen
der sfv-Datei.
Diese beinhaltet unseren Dateinamen für die zu prüfende Datei
sowie die Prüfsumme an sich. Wieder überprüfen wir zuerst, ob die sfv-Datei
vorhanden ist (67), bevor wir sie einlesen (68). Die Funktion file() liest
unsere sfv-Datei
zeilenweise in ein Array ein.
Da wir wissen, dass unsere Zeile an der vierten Position ist und somit im
Array den Index 3 hat, ist es nun kein Problem, den Wertebereich auszulesen.
Wir trennen also unsere Zeile anhand des Leerzeichens mit der Funktion
explode() (69) und erhalten als Ergebnis ein Array mit zwei Einträgen.
Im Index 0 (Null) des Arrays befindet sich unser Dateiname und im Index 1
(Eins) unsere Prüfsumme. Nachdem wir überprüft haben, ob die Backupdatei
vorhanden ist (71), können wir jetzt den kompletten Inhalt der Backupdatei
mit file_get_contents() ( wahlweise auch mit fread() ) in die Variable
$content (72) einlesen.
Wieder errechnen wir die Prüfsumme der Datei (73) und vergleichen sie (75)
mit der Prüfsumme aus unserer sfv-Datei.
Wichtig ist hierbei allerdings, dass die Prüfsumme aus der sfvDatei
in hexadezimaler Darstellung vorliegt, hingegen
aber die gerade erstellte Prüfsumme in dezimaler Darstellung. Daher
konvertieren wir (75) die Prüfsumme aus der sfv-Datei
mit hexdec() in eine
dezimale Darstellung.
Sollte der Vergleich erfolgreich sein, so wird die Funktion TRUE zurückliefern,
also dass die Datei nicht beschädigt ist, ansonsten FALSE.
065: 066: 067: 068: 069: 070: 071: 072: 073: 074: 075: 076: 077: 078: 079: 080: 081: 082: 083: 084: |
function checkCRC($file)
{
if(file_exists($file)) {
$sfvString = file($file); $sfv = explode(" ", $sfvString[3]); if(file_exists($sfv[0])) {
$content = file_get_contents($sfv[0]); $crc = crc32($content); if($crc == hexdec($sfv[1])) return true; else return false; } } return false; }
|
Beispiel 12.5: crc.php
Bei der Überprüfung ist es völlig egal, welchen Dateityp Sie überprüfen möchten.
Sie sollten allerdings die sfv-Dateien
an einem sicheren Ort aufbewahren,
da diese die Prüfsummen enthalten. Sie könnten mit dieser zyklischen Redundanzprüfung
z. B. auch Ihre Website bereichern und Dateien zum Download
anbieten, dazu die passende sfv-Datei.
Ihre Besucher wären dann in der Lage,
z. B. mit DF CrcSfv die Datei selbst zu überprüfen.
086: 087: 088: 089: 090: 091: 092: 093: 094: 095: 096: 097: 098:
| // Name der Datei
$fileCRC = 'pecl-5.1.2-Win32.zip';
// Name der sfv-Datei $fileSFV = 'pecl-5.1.2-Win32.zip.sfv';
if(createCRC($fileCRC)) echo 'sfv-Datei wurde erstellt<br>'; if(checkCRC($fileSFV)) echo 'Datei ist unbeschädigt<br>'; else echo 'Datei ist beschädigt.'; |
Beispiel 12.6: crc.php
Das Beispiel zeigt, wie man mit wenig Aufwand eine fast sichere Überprüfung
vornimmt. Wie aber bereits erwähnt, ist es lediglich für beschädigte Dateien
wirklich sinnvoll. Ein Schutz ist nicht gewährleistet! Sie werden aber in einem
folgenden Beispiel sehen, wie diese Lücke geschlossen werden kann.
Die Darstellung der Ausgabe können Sie selbst beeinflussen. Je nachdem
erhalten Sie von den Funktionen entweder TRUE bei Erfolg oder FALSE bei
Misserfolg zurückgeliefert.
sfv-Datei
wurde erstellt Datei ist unbeschädigt |
Dieses Skript aus dem SELFPHP KOCHBUCH wurde von SELFPHP unter dem "Tarif Mc500" von McAc.net-Webhosting erfolgreich ausgeführt und getestet!
Auf der Übersichtseite unter "McAc.net – Webhosting zu diesem Buch" finden Sie weitere Informationen zu dem Webhostingpaket, dass durch SELFPHP getestet wurde.
|