2012-05-24 29 views
25

Nếu tôi làm:Sẽ md5 (file_contents_as_string) bằng md5_file (/ path/to/file) không?

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

... sẽ này luôn tạo ra các hash giống như:

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

+5

Hm, không thể nói chắc chắn, nhưng nếu tệp có chứa [dấu thứ tự byte] (http://en.wikipedia.org/wiki/Byte_order_mark) và chuỗi thì không được băm sẽ không công bằng. – vcsjones

+4

[để trả lời bình luận đã xóa] Tôi có thể tự mình thử. Tôi chỉ lo lắng rằng nếu tôi nhận được một trận đấu và tôi bắt đầu so sánh md5() với md5_file() có thể có vấn đề xuống dòng sản xuất băm khác nhau - có thể làm với chỉ thị php_ini hoặc một số cách như vậy trên đầu của tôi là một cơn ác mộng để gỡ lỗi/xác định. – Tom

Trả lời

25

Có họ trở về như cũ:

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

mà trả lại số tiền này trong trường hợp của tôi:

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

Chỉnh sửa: Hãy xem mã nguồn của cả hai chức năng: https://github.com/php/php-src/blob/master/ext/standard/md5.c (Dòng 47 & 76). Cả hai đều sử dụng các hàm giống nhau để tạo hàm băm ngoại trừ hàm md5_file() mở tệp trước.

Chỉnh sửa lần thứ hai: Về cơ bản, hàm md5_file() tạo hàm băm dựa trên nội dung tệp, không phải trên dữ liệu siêu tệp như tên tệp. Đây là cùng một cách md5sum trên các hệ thống Linux hoạt động. Xem ví dụ này:

[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 lệnh chỉ hashs các nội dung của một tập tin với md5.

Nếu bạn tham khảo cũ thực hiện md5_file PHP (nhưng nguyên tắc vẫn như cũ) 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; 
} 

Vì vậy, nếu bạn băm với md5 bất kỳ chuỗi hoặc nội dung, bạn sẽ luôn luôn nhận được kết quả tương tự như md5_file (cho cùng một mã hóa và nội dung tệp).

Trong trường hợp đó, nếu bạn băm md5 nội dung của tệp với file_get_content() hoặc nếu bạn sử dụng md5_file hoặc thậm chí nếu bạn sử dụng lệnh md5 có cùng nội dung với nội dung tệp của mình, bạn sẽ luôn nhận được kết quả tương tự.

Ví dụ: bạn có thể thay đổi tên tệp của tệp và cho hai tệp khác nhau, với cùng một nội dung, chúng sẽ tạo cùng một hàm băm md5.

By dụ: Xét hai tập tin có chứa "stackoverflow" (không có dấu ngoặc kép) tên là 1.txt và 2.txt

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

sẽ ra

73868cb1848a216984dca1b6b0ee37bc 

Bạn sẽ có chính xác cùng kết quả nếu bạn md5("stackoverflow") hoặc nếu bạn md5(file_get_contents("1.txt")) hoặc md5(file_get_contents("1.txt")).

+0

Nguồn bạn đang đề cập đến là một cài đặt PHP cũ của hàm. Nhưng lời giải thích là tốt. – prehfeldt

+0

Bạn có liên kết mới không? Tôi không có quyền truy cập internet miễn phí và rất nhiều trang web bị chặn ở đây. Nếu bạn có nguồn mới, tôi sẽ cập nhật bài đăng của mình. –

+0

@ pier-alexandre-bouchard ông đã đăng một liên kết tới mã nguồn php đang được đề cập đến trong câu trả lời của chính mình. :) – damianb

2

Có, tôi đã thử nó cho một số lần. Trong trường hợp của tôi, kết quả cho:

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

Sản xuất đầu ra như:

660d4e394937c10cd1c16a98f44457c2 
660d4e394937c10cd1c16a98f44457c2 

Mà dường như tương đương trên cả hai dòng.

3

dựa trên nội dung tập tin, không phải trên siêu dữ liệu tập tin như BOM hoặc filename

Đó không phải là chính xác về BOM. BOM là một phần của nội dung tệp, bạn có thể thấy ba byte của nó trong bất kỳ trình chỉnh sửa tệp không phải unicode nào.

+2

Đây phải là nhận xét về câu trả lời mà bạn trích dẫn, không phải là câu trả lời. – BHSPitMonkey