Wenn man den hash eines Dateinhalts als Dateiname benutzt sollte man die PHP-Funktionen md5_file()
bzw. sha1_file()
benutzen.
Will man den hash als Dateiname (oder nur ermitteln) und soll es ein SHA512-Hash sein, dann ist es definitiv unvorteilhaft, hash( 'sha512', file_get_contents( datei );
zu benutzen. Besser ist es, hier, die Rückgabe des Shell-Befehls openssl sha512 datei
zu verwerten.
Das Experiment:
<?php
function myFileHashSHA512( $file ) {
$openssl = '/usr/bin/openssl';
if ( is_executable( $openssl ) ) {
$cmd = $openssl . ' SHA512 < "' . str_replace( '"', '\"', $file ) . '"';
return trim( str_replace ( '(stdin)= ', '', `$cmd` ) );
} else {
trigger_error( "$openssl ist nicht installiert, hash_file('sha512') wurde benutzt", E_USER_NOTICE );
echo "PHP: hash_file( 'sha512', ${file} )" . PHP_EOL;
#return hash( 'sha512', file_get_contents( $file ) );
return hash_file( 'sha512', $file );
}
}
# 1GB große Datei:
$file = "/home/fastix/vmware/Andere/TrueNAS12/TrueNAS12-s001.vmdk";
echo myFileHashSHA512( $file ) , PHP_EOL;
echo memory_get_peak_usage() , " Bytes benutzt." , PHP_EOL;
Erstes Ergebnis - mit korrektem pfad zu openssl:
time php test.php
fc5796bf3eb413e54bdf12c3feec6a8733d29487385dd36f5a5cf1600167836a8078d3d588ef6ecb209967e0f7126c763d294e4d32736537f84a97706473bdb1
433560 Bytes benutzt.
real 0m1,708s
user 0m1,557s
sys 0m0,140s
Zweites Ergebnis - falscher Pfad zu openssl, hash_file() wird benutzt:
fastix@trainer:/tmp$ time php test.php
PHP Notice: foo/usr/bin/openssl ist nicht installiert, hash_file('sha512') wurde benutzt in /tmp/test.php on line 14
PHP: hash_file( 'sha512', /home/fastix/vmware/Andere/TrueNAS12/TrueNAS12-s001.vmdk )
fc5796bf3eb413e54bdf12c3feec6a8733d29487385dd36f5a5cf1600167836a8078d3d588ef6ecb209967e0f7126c763d294e4d32736537f84a97706473bdb1
432344 Bytes benutzt.
real 0m3,241s
user 0m3,065s
sys 0m0,164s
Der Hash ist (natürlich) der gleiche - aber die benötigte Zeit unterscheidet sich erheblich: Zumindest derzeit ist das Linux-Programm openssl
deutlich schneller als das sehr aktuelle PHP 8.0.5 (cli) (built: May 3 2021 11:30:57) ( NTS ).
Benutzt man die Funktionen
- md5( file_get_contents( $file ) ),
- sha1( file_get_contents( $file ) ),
- hash('sha512', file_get_contents( $file ) )
wird man anhand derAusgaben von memory_get_peak_usage()
sehr genau sehen, was man falsch gemacht hat… Damit habe ich es auf bis zu 1109154016 (1.109.154.016 ~ 1 GB statt 430KB) gebracht.
Wer will kann ja auch md5_file()
vers. openssl MD5
bzw. openssl SHA1
vers. sha1_file()
testen…