PHP Conference Japan 2024

hash_file

(PHP 5 >= 5.1.2,PHP 7,PHP 8,PECL hash >= 1.1)

hash_file使用给定文件的内容生成哈希值

描述

hash_file(
    字符串 $algo,
    字符串 $filename,
    布尔值 $binary = false,
    数组 $options = []
): 字符串|false

参数

algo

所选哈希算法的名称(例如 "sha256")。有关支持的算法列表,请参见 hash_algos()

filename

描述要哈希的文件位置的 URL;支持 fopen() 封装器。

binary

设置为 true 时,输出原始二进制数据。false 输出小写十六进制数字。

options

各种哈希算法的选项数组。目前,只有 "seed" 参数受 MurmurHash 变体支持。

返回值

返回一个字符串,其中包含计算出的消息摘要作为小写十六进制数字,除非 binary 设置为 true,在这种情况下,将返回消息摘要的原始二进制表示形式。

变更日志

版本 描述
8.1.0 添加了 options 参数。

示例

示例 #1 使用 hash_file()

<?php
/* 创建一个要计算哈希的文件 */
file_put_contents('example.txt', 'The quick brown fox jumped over the lazy dog.');

echo
hash_file('sha256', 'example.txt');
?>

以上示例将输出

68b1282b91de2c054c36629cb8dd447f12f096d3e3c587978dc2248444633483

参见

  • hash_init() - 初始化增量哈希上下文
  • hash_hmac_file() - 使用 HMAC 方法和给定文件的内容生成带密钥的哈希值

添加注释

用户贡献的注释 8 条注释

apm at domain itsmee.co.uk
13 年前
我已验证“crc32”的输出是 ITU I.363.5 算法(也称为 AAL5 CRC - 由 BZIP2 推广,但也用于 ATM 传输 - 该算法与 POSIX 1003.2-1992 中的 Cksum 中的算法相同,但它在最后将大小填充到 CRC 中以进行额外测量)。但是,输出以与许多 CRC 程序相反的顺序表示。使用“标准”crctest.txt(按顺序排列的数字 1 到 9 - 谷歌搜索一下,不难找到),php 将输出 181989fc - 许多其他(Intel 小端)程序会将其输出为 fc891918,因此会造成混淆(至少我遇到了)。

crc32b 是 ITU V.42 的 32 位帧校验序列(用于以太网并由 PKZip 推广)。此 CRC 的输出在 Intel 小端格式中很流行,并且在相同的文件上会产生 cbf43926。
chernyshevsky at hotmail dot com
14 年前
如果要使用 hash_file() 获取文件的 CRC32 值,请使用以下方法将函数返回的十六进制字符串解包为整数(类似于 crc32())

$hash = hash_file('crc32b', $filepath);
$array = unpack('N', pack('H*', $hash));
$crc32 = $array[1];
synnus at gmail dot com
9 年前
基准测试 476 Mo,获胜者为 'haval160,4':0.037002

算法:md2,时间:74.702272891998
算法:md4,时间:9.2155270576477
算法:md5,时间:9.0815191268921
算法:sha1,时间:9.0945210456848
算法:sha224,时间:9.1465229988098
算法:sha256,时间:9.143522977829
算法:sha384,时间:14.065804004669
算法:sha512,时间:13.990800857544
算法:ripemd128,时间:9.3185329437256
算法:ripemd160,时间:9.3165328502655
算法:ripemd256,时间:9.2495288848877
算法:ripemd320,时间:9.2395279407501
算法:whirlpool,时间:27.779588937759
算法:tiger128,3,时间:9.3075330257416
算法:tiger160,3,时间:9.1875250339508
算法:tiger192,3,时间:9.3875370025635
算法:tiger128,4,时间:9.1755249500275
算法:tiger160,4,时间:9.355535030365
算法:tiger192,4,时间:9.2025260925293
算法:snefru,时间:42.781446218491
算法:snefru256,时间:42.613437175751
算法:gost,时间:18.606064081192
算法:gost-crypto,时间:18.664067983627
算法:adler32,时间:9.1535229682922
算法:crc32,时间:10.126579999924
算法:crc32b,时间:10.01757311821
算法:fnv132,时间:9.7505569458008
算法:fnv1a32,时间:9.7935597896576
算法:fnv164,时间:9.8945660591125
算法:fnv1a64,时间:9.3025319576263
算法:joaat,时间:9.7175559997559
算法:haval128,3,时间:9.6855540275574
算法:haval160,3,时间:10.10857796669
算法:haval192,3,时间:9.6765530109406
算法:haval224,3,时间:20.636180877686
算法:haval256,3,时间:10.641607999802
算法:haval128,4,时间:7.5594329833984
算法:haval160,4,时间:7.2884171009064
算法:haval192,4,时间:7.2934169769287
算法:haval224,4,时间:7.2964169979095
算法:haval256,4,时间:7.3034179210663
算法:haval128,5,时间:8.3244760036469
算法:haval160,5,时间:8.3174757957458
算法:haval192,5,时间:8.3204758167267
算法:haval224,5,时间:8.3234758377075
算法:haval256,5,时间:8.3254759311676

基准测试 13.0 Mo,获胜者为 'adler32':0.037002

算法:md2,时间:2.0341160297394
算法:md4,时间:0.062004089355469
算法:md5,时间:0.071003913879395
算法:sha1,时间:0.086004972457886
算法:sha224,时间:0.18301010131836
算法:sha256,时间:0.18301105499268
算法:sha384,时间:0.36102104187012
算法:sha512,时间:0.3610200881958
算法:ripemd128,时间:0.15900897979736
算法:ripemd160,时间:0.20701193809509
算法:ripemd256,时间:0.16500997543335
算法:ripemd320,时间:0.22501301765442
算法:whirlpool,时间:0.74204206466675
算法:tiger128,3,时间:0.12200689315796
算法:tiger160,3,时间:0.12100696563721
算法:tiger192,3,时间:0.12200713157654
算法:tiger128,4,时间:0.15700888633728
算法:tiger160,4,时间:0.15700888633728
算法:tiger192,4,时间:0.15600895881653
算法:snefru,时间:1.1520659923553
算法:snefru256,时间:1.151065826416
算法:gost,时间:0.48902797698975
算法:gost-crypto,时间:0.49202799797058
算法:adler32,时间:0.037002086639404
算法:crc32,时间:0.10300588607788
算法:crc32b,时间:0.093006134033203
算法:fnv132,时间:0.043002128601074
算法:fnv1a32,时间:0.045002937316895
算法:fnv164,时间:0.12800693511963
算法:fnv1a64,时间:0.12800693511963
算法:joaat,时间:0.070003986358643
算法:haval128,3,时间:0.12900686264038
算法:haval160,3,时间:0.12800693511963
算法:haval192,3,时间:0.12900805473328
算法:haval224,3,时间:0.12800693511963
算法:haval256,3,时间:0.12800693511963
算法:haval128,4,时间:0.19901204109192
算法:haval160,4,时间:0.1990110874176
算法:haval192,4,时间:0.20001196861267
算法:haval224,4,时间:0.20001101493835
算法:haval256,4,时间:0.20001220703125
算法:haval128,5,时间:0.22601294517517
算法:haval160,5,时间:0.2270131111145
算法:haval192,5,时间:0.2270131111145
算法:haval224,5,时间:0.2270131111145
算法:haval256,5,时间:0.22701287269592
lnker dot ua at gmail dot com
7 年前
链接 ID:6r1j-d2gs
代码描述:hash_file() 性能检查;表头列可以通过点击排序。

使用 PhpFiddle 打开代码 - http://phpfiddle.org/main/code/6r1j-d2gs
使用 PhpFiddle Lite 打开代码 - http://phpfiddle.org/lite/code/6r1j-d2gs

所以不要太关心性能!只需使用你需要的功能即可!
Keisial at gmail dot com
16 年前
你看到的“字节反转”是 bug 45028,该 bug 已经被修复。 http://bugs.php.net/bug.php?id=45028

crc32 和 crc32b 之间的区别在 mhash 手册页中解释。crc32 是以太网中使用的算法,而 crc32b 是 zip、png 等中使用的算法。它们使用的查找表不同。
holdoffhunger at gmail dot com
12 年前
Hash_File() 函数返回的值与对相同数据片段执行 Hash() 函数的结果相同。最初,我不确定 Hash_File() 在定义要为给定算法散列的数据时是否使用了文件名,甚至权限设置。如果它确实以这种方式工作,那么这意味着当你在系统上移动或重命名相同的文件时,它们将具有不同的 HASH 值。无论如何,幸运的是,它不是这样工作的。Hash() 和 Hash_File() 对相同的数据片段产生相同的结果。这对于 Hash_HMAC() 和 Hash_HMAC_File() 函数之间的关系也适用:相同的数据片段,相同的密钥,产生相同的结果。这是一个明智的设计原则。

一些示例代码来演示此原则

<?php

// 作者:[email protected]

// 预设数据
// ------------------------------------------------

$test_data = "php-hashing";
$test_file = "test.txt";
$test_file_read = file_get_contents($test_file);

// 散列数据
// ------------------------------------------------

$test_data_hash = hash("md2", $test_data, FALSE);
$test_file_hash = hash_file("md2", $test_file, FALSE);

// 打印散列结果
// ------------------------------------------------

print("数据散列 ($test_data): $test_data_hash<br><br>");
print(
"文件散列 ($test_file_read): $test_file_hash");

?>

预期结果
..................................

数据散列 (php-hashing): 457d84e1d69e519a7b73348db21477d3

文件散列 (php-hashing): 457d84e1d69e519a7b73348db21477d3
Lawrence Cherone
6 年前
有时需要使用不同的算法散列相同的文件。

<?php
function hash_file_multi($algos = [], $filename) {
if (!
is_array($algos)) {
throw new
\InvalidArgumentException('第一个参数必须是数组');
}

if (!
is_string($filename)) {
throw new
\InvalidArgumentException('第二个参数必须是字符串');
}

if (!
file_exists($filename)) {
throw new
\InvalidArgumentException('第二个参数,文件未找到');
}

$result = [];
$fp = fopen($filename, "r");
if (
$fp) {
// 初始化散列上下文
foreach ($algos as $algo) {
$ctx[$algo] = hash_init($algo);
}

// 计算散列
while (!feof($fp)) {
$buffer = fgets($fp, 65536);
foreach (
$ctx as $key => $context) {
hash_update($ctx[$key], $buffer);
}
}

// 完成散列并存储在返回值中
foreach ($algos as $algo) {
$result[$algo] = hash_final($ctx[$algo]);
}

fclose($fp);
} else {
throw new
\InvalidArgumentException('无法打开文件以供读取');
}
return
$result;
}
?>

使用方法如下

<?php
$result
= hash_file_multi(['md5', 'sha1', 'sha256'], 'path/to/file.ext');

var_dump($result['md5'] === hash_file('md5', 'path/to/file.ext')); //true
var_dump($result['sha1'] === hash_file('sha1', 'path/to/file.ext')); //true
var_dump($result['sha256'] === hash_file('sha256', 'path/to/file.ext')); //true
匿名用户
13 年前
请注意,对于大于等于 2GB 的文件,hash-file 会抛出错误。
To Top