在PHP中比较文件校验和

在PHP中比较文件校验和,php,file-upload,checksum,Php,File Upload,Checksum,我正在写一个文件上传网站,并对节省空间感兴趣。如果用户上传了一个文件,我想确保这个文件以前没有上传过(如果已经上传过,我只会指向数据库中的现有文件) 我正在考虑在文件上使用sha1_file(),检查数据库以查看摘要数据库中是否存在摘要。然后我想起了鸽子洞原则,并决定检查未消化的文件,如果有一个sha1摘要匹配 这对我来说似乎效率低下。我想我可以在校验和匹配的情况下检查每个文件的第一个KB 我没有过多考虑RAM与ROM的价值,检查文件所需的处理能力可能比我节省的存储空间更贵 这种方法有什么缺点吗

我正在写一个文件上传网站,并对节省空间感兴趣。如果用户上传了一个文件,我想确保这个文件以前没有上传过(如果已经上传过,我只会指向数据库中的现有文件)


我正在考虑在文件上使用
sha1_file()
,检查数据库以查看摘要数据库中是否存在摘要。然后我想起了鸽子洞原则,并决定检查未消化的文件,如果有一个sha1摘要匹配

这对我来说似乎效率低下。我想我可以在校验和匹配的情况下检查每个文件的第一个KB

我没有过多考虑RAM与ROM的价值,检查文件所需的处理能力可能比我节省的存储空间更贵


这种方法有什么缺点吗?我是不是在浪费时间呢?

你可以使用
md5(文件数据)
来生成文件名,而且永远不可能用不同的名称上传同一个文件。唯一的问题是,在技术上可能两个不同的文件生成相同的MD5,但它不太可能,特别是如果两个文件具有相同的扩展,那么您可以认为这是一个非问题。在这个示意图下,甚至没有理由检查。如果两个哈希值相同,它只会覆盖存储的文件。这就是大多数文件存储引擎在内部的工作方式,例如。如果您对冲突心存疑虑,您可以首先查看文件是否存在计算出的哈希和扩展名,如果存在,您可以将存储的文件的数据与尝试存储的文件的数据进行比较。如果数据不相等,您可以让它通过电子邮件通知您

$data = file_get_contents('flowers.jpg');

$name = md5($data).'.jpg';

$fh = fopen($name,'w+');

fwrite($fh,$data);

fclose($fh);

“我是不是在浪费我的时间来处理这个问题?”-这取决于成本/收益比率。但从学术角度来看,这个问题似乎很有趣。“然后我想起了鸽子洞原理,决定检查未消化的文件,如果有sha1摘要匹配的话。”-你能更好地解释一下吗。我不明白你的意思。您没有使用散列数据库,只是每次比较文件?如果文件相似,则其大小必须相等。每个文件系统都可以提供文件大小,这是一种廉价的操作。找到大小相同的文件,然后比较散列。鸽子洞原理适用于冲突。如果我有两个大小为32kB的文件和一个生成64B输出的哈希算法,则冲突的可能性比我的输出为512B时要高。我可能会使用检查文件大小、检查整个文件摘要的组合,然后在发生冲突时检查文件本身。想想看——Facebook使用多个摘要作为图像名称。我猜其中一个是用户ID,但它让我意识到,即使一个哈希算法可能会冲突,另一个可能不会。如果你对碰撞心存疑虑,你可以用CRC之类的快速校验和来消化文件,然后再使用计算强度更高的校验和来消化原始数据;最后,将合并摘要,并将文件另存为。