2012-05-24 9 views
25

Wenn ich tun:Wird md5 (file_contents_as_string) gleich md5_file (/ pfad/zu/datei)?

<?php echo md5(file_get_contents("/path/to/file")) ?>

... produzieren diese immer den gleichen Hash wie:

<?php echo md5_file("/path/to/file") ?>

+5

Hm, kann nicht sicher sagen, aber wenn die Datei eine [Byte-Reihenfolge-Markierung] (http://en.wikipedia.org/wiki/Byte_order_mark) enthält und die Zeichenfolge nicht, dann werden die Hashes nicht sein gleich. – vcsjones

+4

[als Reaktion auf gelöschten Kommentar] Ich könnte es selbst ausprobieren. Ich mache mir nur Sorgen, dass, wenn ich eine Übereinstimmung bekomme und ich md5() mit md5_file() vergleiche, es Probleme in der Zeile gibt, die verschiedene Hashes erzeugen - vielleicht mit php_ini-Direktiven oder so etwas über meinen Kopf sei ein Albtraum zum Debuggen/Identifizieren. – Tom

Antwort

25

Ja sie gleich zurück:

var_dump(md5(file_get_contents(__FILE__))); 
var_dump(md5_file(__FILE__)); 

die gibt das in meinem Fall zurück:

string(32) "4d2aec3ae83694513cb9bde0617deeea" 
string(32) "4d2aec3ae83694513cb9bde0617deeea" 

Edit: Werfen Sie einen Blick auf den Quellcode der beiden Funktionen: https://github.com/php/php-src/blob/master/ext/standard/md5.c (Linie 47 & 76). Sie verwenden beide dieselben Funktionen, um den Hash zu generieren, außer dass die Funktion md5_file() die Datei zuerst öffnet.

2nd Edit: Grundsätzlich generiert die md5_file()-Funktion den Hash basierend auf dem Dateiinhalt, nicht auf der Datei Metadaten wie der Dateiname. Dies ist der gleiche Weg md5sum auf Linux-Systemen arbeiten. Sehen Sie folgendes Beispiel:

[email protected]:~# echo foobar > foo.txt 
[email protected]:~# md5sum foo.txt 
14758f1afd44c09b7992073ccf00b43d foo.txt 
[email protected]:~# mv foo.txt bar.txt 
[email protected]:~# md5sum bar.txt 
14758f1afd44c09b7992073ccf00b43d bar.txt 
3

md5_file Befehl hashs nur den Inhalt einer Datei mit md5.

Wenn Sie an die alte md5_file PHP Implementierung verweisen (aber das Prinzip ist immer noch das gleiche) source:

function php_compat_md5_file($filename, $raw_output = false) 
{ 
// ... 
// removed protections 

if ($fsize = @filesize($filename)) { 
     $data = fread($fh, $fsize); 
    } else { 
     $data = ''; 
     while (!feof($fh)) { 
      $data .= fread($fh, 8192); 
     } 
    } 

    fclose($fh); 

    // Return 
    $data = md5($data); 
    if ($raw_output === true) { 
     $data = pack('H*', $data); 
    } 

    return $data; 
} 

Also, wenn Sie mit md5 beliebige Zeichenfolge oder Inhalt Hash, werden Sie immer das gleiche Ergebnis wie md5_file (für die gleiche Kodierung und Dateiinhalt).

In diesem Fall, wenn Sie mit dem md5 den Inhalts einer Datei Hash mit file_get_content() oder wenn Sie md5_file verwenden oder auch wenn Sie verwenden md5 Befehl mit dem gleichen Inhalt wie Ihr Dateiinhalt, werden Sie immer das gleiche Ergebnis.

Zum Beispiel könnten Sie den Dateinamen einer Datei ändern, und für zwei verschiedene Dateien, mit dem gleichen Inhalt, werden sie den gleichen MD5-Hash erzeugen.

von Beispiel: Betrachtet man zwei Dateien "Stackoverflow" (ohne Anführungszeichen) mit dem Namen 1.txt und 2.txt enthält

md5_file("1.txt"); 
md5_file("2.txt"); 

würde Ausgang

73868cb1848a216984dca1b6b0ee37bc 

Sie werden genau das gleiche haben Ergebnis wenn Sie md5("stackoverflow") oder wenn Sie md5(file_get_contents("1.txt")) oder md5(file_get_contents("1.txt")).

+0

Die Quelle, auf die Sie sich beziehen, ist eine alte PHP-Implementierung der Funktion. Aber die Erklärung ist gut. – prehfeldt

+0

Haben Sie den neuen Link? Ich habe keinen kostenlosen Internetzugang und so viele Webseiten sind hier blockiert. Wenn Sie die neue Quelle haben, werde ich meinen Beitrag aktualisieren. –

+0

@ pier-alexandre-bouchard er hat in seiner eigenen antwort einen link auf den fraglichen php-quellcode gepostet. :) – damianb

2

Ja, habe ich es für mehrere versucht mal. In meinem Fall Ergebnis für:

<?php echo md5(file_get_contents("1.php")) ?> 
<br/> 
<?php echo md5_file("1.php") ?> 

Produce Ausgabe als:

660d4e394937c10cd1c16a98f44457c2 
660d4e394937c10cd1c16a98f44457c2 

, die auf beiden Linien gleichwertig zu sein scheint.

3

basierend auf dem Inhalt der Datei, nicht auf den Datei-Metadaten wie die Stückliste oder Dateinamen

Die über BOM nicht korrekt ist. BOM ist ein Teil des Dateiinhalts, Sie können seine drei Bytes in einem beliebigen Nicht-Unicode-Dateieditor sehen.

+2

Dies sollte ein Kommentar zu der Antwort sein, aus der Ihr Zitat stammt, und keine Antwort allein. – BHSPitMonkey