【问题标题】:SHA-1 hash for storing Files用于存储文件的 SHA-1 哈希
【发布时间】:2009-11-22 17:12:35
【问题描述】:

在阅读this 之后,使用 SHA-1 作为目录存储文件听起来是个好主意。

我不知道这意味着什么,但我只知道 SHA-1 和 MD5 是散列算法。如果我使用this ruby script 计算 SHA-1 哈希,并更改文件的内容(这会更改哈希),那么我如何知道文件的存储位置?

那么我的问题是,实现 SHA-1/文件存储系统的基础是什么?

如果所有文件都一直在更改内容,是否有更好的解决方案来存储它们,还是只需要不断更新哈希?

我只是在考虑如何创建一个通用的文件存储系统,如 GoogleDocs、Flickr、Youtube、DropBox 等,您可以在不同的环境中重复使用这些系统(例如存储 PubMed 期刊文章或 Cramster家庭作业和测试,或者只是像 Flickr 上的图像)。我可能会将它们存储在 Amazon EC2 上。只是一些系统,所以我可以说“从现在开始,我将在 99% 的时间里进行文件存储”,所以我可以停止考虑构建一种可靠/一致的方式来存储文件并解决一些实际问题。

【问题讨论】:

  • 我认为这个想法是在存储在路径之前计算哈希值(在您更改文件内容之后)。这样你应该没有问题?
  • 所以如果所有文件都一直在更改内容,是否有更好的解决方案来存储它们,还是只需要不断更新哈希?
  • 您只需使用初始哈希。你不需要不断更新。将哈希值保存在数据库中。
  • 散列解决了 2 个问题(为不太可能发生冲突的文件选择名称,并通过将散列拆分成形成路径的部分来避免在某些文件系统上处理字典中大量文件的性能问题)。这已成为一种最佳实践,一些框架可以帮助您。尽管如果您指定您打算如何处理这些文件,您可能会获得更精确/适用的解决方案/答案:)

标签: ruby file-storage sha1


【解决方案1】:

我看到使用哈希存储文件的一个优点是文件数据只需要存储一次,然后可以在数据库中多次引用。如果您有不同的用户上传完全相同的文件,这将节省您的空间。

但是,这样做的不利之处在于,当用户从您的应用中删除他们认为存在的文件时,您不能只是从磁盘中物理删除该文件,因为上传相同文件的其他用户可能仍在使用它。

【讨论】:

    【解决方案2】:

    首先,如果文件内容发生变化,SHA-digest方法的文件名不是很合适,因为文件内容变化时文件名和文件在文件系统中的位置必须改变。


    基本上,您首先从文件的内容中计算出 SHA-1 或 MD5 摘要(= 哈希值)。

    当您有摘要时,例如 00e4f56c0de1c61fdb926e79e8a0a65bd12930c9,您会根据摘要生成文件位置和文件名。例如,您将摘要中的前几个字符拆分为目录结构,将其余字符拆分为文件名。例如:

     00e4f56c0de1c61fdb926e79e8a0a65bd12930c9 => some/path/00/e4/f5/6c0de1c61fdb926e79e8a0a65bd12930c9.txt
    

    这样您只需将文件的 SHA-1 摘要存储到数据库中。然后,您总能找到正确的位置和文件名。

    目录通常也具有它们可以包含的最大文件数,例如每个目录最多 32000 个子目录和文件。基于这种散列的目录结构使您不太可能将太多文件存储到同一个目录中。同样使用这样的散列确保每个目录都有大约相同数量的文件,您不会遇到所有文件都在同一个目录中的情况。

    【讨论】:

    • 好的,然后您将文件名和一些标签与哈希以及其他任何内容一起存储在数据库中,您可以从文件系统中获取带有哈希的文件。这样,您可以使用文件引用存储一些人类可读的信息,但没有文件本身。哈希只是为了使其统一、优化和易于编程,它不需要是人类可读的。明白了,谢谢!
    • @viatropos,是的,就是这样。您还可以从序列中为每个文件指定一个唯一编号,并使用该编号代替 SHA-1 摘要。
    • 如果您打算使用相同路径将旧文件替换为新版本,请确保操作是原子操作。否则,如果有人在您写下新文件时请求该文件,您可能会遇到麻烦。恕我直言,将新文件保存到另一个位置不会有什么坏处。如果遇到存储空间问题,请考虑不时删除旧/过时版本的方法:)
    • 但是删除呢?示例:2 个用户上传了同一个文件。所以只有一个文件存在,因为哈希(路径)是相同的。当其中一个人删除照片时,第二个用户也会丢失它。我说的对吗?
    • 您必须为每个文件保留一个计数器,以告知给定文件有多少“副本”。在每次更新时,递增计数器,在每次删除时,递减计数器。如果计数器归零,则删除文件是安全的。您可以保留计数器,例如在数据库中。
    【解决方案3】:

    这个想法不是通过使用哈希值来更改文件内容,而是更改其名称(和路径)。

    使用哈希更改内容将是灾难性的,因为哈希通常是不可逆的。

    我不确定使用 hash 而不是文件名(甚至不是长随机数)的动机,但这里有一些哈希方法的优点:

    • 磁盘上的文件名是统一的
    • 哈希值的上半部分或下半部分可用于命名目录,从而相对均匀地分布文件
    • 名字变成了代码,让人很难 a) 猜一个文件名 b) 对图片进行分类(会不会有人窃取硬盘内容)
    • 能够从文件内容本身中检索文件名和位置(假设哈希来自此类内容。(不太确定哪个用例会涉及这个...有点人为...)

    使用散列的普遍意义在于,与文件名不同,散列是无意义的,因此需要数据库将图像和“书目”类型数据(上传者名称、上传日期、标签、. ..)

    考虑到这一点,重新阅读引用的 SO 响应,我并没有真正看到哈希与随机数相比有多大优势......

    此外...一些哈希产生一个数值,通常以十六进制表示(如引用的 SO 问题中所见),这可能被视为浪费,因为文件名比它们需要的长,因此放对文件系统的压力更大(更大的目录...)

    【讨论】:

    • 如果您使用哈希,那么相同文件的多个相同副本将存储到相同位置。使用随机数,文件将存储到不同的位置。根据您的情况,这可能是优点或缺点。
    • 像 flickr 或 facebook 这样的人是做什么的?
    • 这里有一些关于 facebook 照片存储基础设施的有趣信息facebook.com/note.php?note_id=76191543919
    【解决方案4】:

    这个想法是您需要为照片命名,并且您可能希望将文件分散在多个目录中。想出唯一名称的一种简单方法是使用哈希。

    因此,散列的开头被剥离用于多级目录结构,其余的散列用于 jpg 的文件名。

    这具有检测重复上传的额外好处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 2013-12-23
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      • 2017-02-26
      • 2017-08-19
      相关资源
      最近更新 更多