如何避免重复文件上传但保持上传者不知道它?

时间:2017-11-15 17:14:16

标签: php file-upload

首先,如果问题不明确,我道歉,我在下面解释。

对于上传的每个文件,我都要重命名文件并记录哈希值(使用sha1_files函数,请在单独的数据库表中建议,如果php中的文件有更好或更快的哈希技术)并检查每个新文件的哈希值,以避免重复文件。

以这种方式,上传重复文件的人将收到错误消息,并且文件不会被上传。

我的问题是,是否有任何技术或算法可以阻止重复文件上传,但重复文件上传者将不知道它并且会在他/她的帐户中找到与其已存在的名称不同的文件。但是,用户无法通过任何方式上传禁止的文件。

4 个答案:

答案 0 :(得分:2)

是的,您应该使用比{1}快得多的xxhash

根据他们的基准:

  

基准测试使用SMHasher速度测试,用Visual 2010编译   Windows 7 32位盒子。参考系统使用Core 2 Duo   @ 3GHz的

SHA1-32 0.28 GB / s 快,xxHash 5.4 GB / s

PHP library只是输入一个字符串,所以你应该使用二进制库,并在你的PHP中有这样的东西:

list($hash) = explode(" ", shell_exec("/path/to/xxHash/xxhsum " . escapeshellarg($filePath)));
echo $hash;

安装xxhash:

$ wget https://codeload.github.com/Cyan4973/xxHash/tar.gz/v0.6.3 -O xx.tar.gz
$ tar xvzf xx.tar.gz
$ cd xxHash-0.6.3; make

答案 1 :(得分:0)

只需在代码中添加一些额外的逻辑,可能使用额外的表或现有表中的额外字段(这取决于您,有多种方法可以执行此操作),如果您将文件保存到备用位置发现它是重复而不是发送错误。但是,不确定,从UI设计的角度来看,如果您正在做的是一个好主意,因为您正在以用户将注意到的方式执行与用户输入不同的操作,而不会告诉用户原因。

答案 2 :(得分:0)

使用像this这样的示例在上传之前生成sha1哈希客户端。

使用散列作为文件名保存所有上传的文件,或者使用包含每个文件的散列和本地文件名的数据库表,同时保存文件大小和内容类型。

在上传之前,从客户端向服务器提交哈希并检查数据库中的哈希值。如果它不存在则开始上传文件。如果存在,则假冒上传客户端或您想要做的任何事情,以便用户认为他们已经上传了他们的文件。

在users表中为上传的文件创建一列。在此列中存储序列化的关联数组,其中hash => users_file_name为key =>值对。反序列化并显示给每个用户以维护他们自己的文件名,然后使用readfile为他们提供正确名称的文件,使用哈希选择服务器端

至于您的网址问题。为下载创建一个页面,但也将用户包含在URL中,因此mysite.com/image.php?user=NewBee&image=filename.jpg

在数据库中查询NewBee上传的文件并反序列化该数组。然后:

$upload = $_GET['image'];
foreach($array as $hash => $filename){
        if($filename == $upload)
              $file = $hash;
    }

搜索数据库以获取该文件副本的路径,然后使用readfile,您可以输出相同的文件以及您想要的任何namme。

header("Content-Description: File Transfer");
header("Content-type: {$contenttype}");
header("Content-Disposition: attachment; filename=\"{$filename}\"");
header("Content-Length: " . filesize($file));
header('Pragma: public');
header("Expires: 0");
readfile($file);

答案 3 :(得分:-1)

您可以使用useraccounts创建一个额外的表格,用于链接上传的文件(因此表格中的条目与文件哈希值)。此表可以包含属于特定用户的每个文件的单个文件名(因此同一文件可以为每个用户使用不同的名称)。使用当前技术,您还可以考虑通过javascript在浏览器中创建文件哈希,然后仅在数据库中已经存在具有该哈希的文件的情况下才上传文件,如果是,您可以将此用户链接到文件。

由于评论而增加: 如果你想通过多个网址访问同一个文件,你可以使用像apache的mod_ rewrite这样的东西。我不是那么专家,但你可以看here第一个想法。您可以使用上传脚本动态更新.htaccess。