PHP Conference Japan 2024

sha1_file

(PHP 4 >= 4.3.0, PHP 5, PHP 7, PHP 8)

sha1_file计算文件的 sha1 哈希值

描述

sha1_file(字符串 $filename, 布尔值 $binary = false): 字符串|false

使用 » 美国安全散列算法 1 计算由 filename 指定的文件的 sha1 哈希值,并返回该哈希值。哈希值是一个 40 个字符的十六进制数字。

参数

filename

要散列的文件的文件名。

binary

true 时,以原始二进制格式返回摘要,长度为 20。

返回值

成功时返回字符串,否则返回 false

示例

示例 #1 sha1_file() 示例

<?php
foreach(glob('/home/Kalle/myproject/*.php') as $ent)
{
if(
is_dir($ent))
{
continue;
}

echo
$ent . ' (SHA1: ' . sha1_file($ent) . ')', PHP_EOL;
}
?>

参见

  • hash_file() - 使用给定文件的内容生成哈希值
  • hash_init() - 初始化增量哈希上下文
  • sha1() - 计算字符串的 sha1 哈希值

添加注释

用户贡献的注释 3 条注释

49
xijque at gmail dot com
13 年前
仅供记录 -

正如一些人指出的那样,您有两种方法可以生成文件的哈希值
方法 1 [此函数]:sha1_file($file)
方法 2:sha1(file_get_contents($file))

重要的是要意识到这两种方法不是一回事。如果它们是,我严重怀疑此函数是否存在。

据我所知,关键区别在于文件内容的加载方式。第二种方法在将文件内容传递给 sha1($str) 之前,会将整个 $file 加载到内存中。但是,方法二在创建哈希值时按需加载 $file 的内容。

如果您能保证您只需要散列相对较小的文件,则此差异意义不大。但是,如果您有较大的文件,则将整个文件加载到内存中是一个坏主意:最好的情况是,您的服务器在尝试处理请求时会变慢;最坏的情况是,您耗尽内存并且根本无法获取哈希值。

如果您决定自己加载文件内容,而不是使用此函数,请记住这一点。在我的系统上,我能够使用此函数在 22 秒内生成 2.6GB 文件的哈希值,而我无法使用第二种方法,因为出现了内存不足错误(耗时 185 秒)。
3
gubatron at gmail dot com
18 年前
像 LimeWire 这样的 P2P 程序使用 sha1 来识别文件。但是它们以 base32 的方式进行。如果您想用 PHP5 编写 Gnutella 客户端,这里有一个实用程序类

/**
PHP5 的实用程序 base32 SHA1 类
版权所有 (C) 2006 Karl Magdsick(原始 Python 作者)
Angel Leon(移植到 PHP5)
Lime Wire LLC

此程序是免费软件;您可以重新分发和/或
根据自由软件基金会发布的 GNU 通用公共许可证修改它
作为许可证版本 2
或(根据您的选择)任何更高版本。

此程序分发是为了希望它有用,
但没有任何保证;甚至没有暗示的适销性或
适合特定用途的保证。有关更多详细信息,请参阅
GNU 通用公共许可证。

您应该已经收到了 GNU 通用公共许可证的副本
以及此程序;如果没有,请写信给自由软件
基金会,公司,51 Franklin Street,五楼,波士顿,马萨诸塞州 02110-1301,美国。
*/
类 SHA1 {
静态 $BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

/** 给定一个文件,它会创建一个 magnetmix */
静态函数 fileSHA1($file) {
$raw = sha1_file($file,true);
return SHA1::base32encode($raw);
} //fileSHA1

/** 获取原始输入并将其转换为 base32 */
静态函数 base32encode($input) {
$output = '';
$position = 0;
$storedData = 0;
$storedBitCount = 0;
$index = 0;

while ($index < strlen($input)) {
$storedData <<= 8;
$storedData += ord($input[$index]);
$storedBitCount += 8;
$index += 1;

//尽可能多地从 storedData 中获取数据
while ($storedBitCount >= 5) {
$storedBitCount -= 5;
$output .= SHA1::$BASE32_ALPHABET[$storedData >> $storedBitCount];
$storedData &= ((1 << $storedBitCount) - 1);
}
} //while

//处理剩余数据
if ($storedBitCount > 0) {
$storedData <<= (5-$storedBitCount);
$output .= SHA1::$BASE32_ALPHABET[$storedData];
}

return $output;
} //base32encode

}
-2
schiros at invisihosting dot com
17 年前
如果您有一个允许用户上传文件的脚本,并且您想防止多次上传相同的文件

<?
session_start();
$isDuplicate = false;
if(isset($_FILES["filename"]["tmp_name"]) && file_exists($_FILES["filename"]["tmp_name"])) {
$fileHash = sha1_file($_FILES["filename"]["tmp_name"]);
if(!isset($_SESSION["check_filelist"])) {
$_SESSION["check_filelist"] = array($fileHash);
}
elseif(in_array($fileHash,$_SESSION["check_filelist"])) {
$isDuplicate = true;
}
else {
$_SESSION["check_filelist"][] = $fileHash;
}

if($isDuplicate) {
echo "您已上传该文件";
}
else{
// 执行一些操作
}
}

?>
To Top