跳到正文

哈希

Hash

中级通用

哈希(Hash)是把数据交给哈希函数,得到一段固定长度结果的过程。这段结果可用来快速比较数据是否变化,例如网站上传文件后,比对上传前后的哈希值来检查内容是否一致。

你可能会说:「我想知道用户上传的文件有没有传完整,不想每次都逐字节人工检查。」

读之前建议先了解

动手看看

SHA-256 不同(红色为不同的字符)

A
B

这两段文字代表上传前后的更新日志。内容相同,SHA-256 摘要就相同,可以用来核对文件内容有没有变化。

试试把右边的 1.4.2 改成 1.4.3,看看摘要:虽然只改了一个字符,得到的摘要也会明显不同。

再把版本号改回来,看看两个摘要是否重新一致。哪怕只是多一个空格,哈希值也会改变,因为空格也是内容的一部分。

要点

  1. 1

    相同输入会得到相同结果

    你用同一种哈希算法处理同一份数据,每次都会得到相同结果。所以我们可以分别计算上传前后的文件哈希,再比较两段结果;相同表示内容很可能一致。

  2. 2

    结果很短但不是原文

    一份很大的文件也能得到固定长度的哈希值,比较起来方便。但哈希值不是文件的压缩副本,不能靠它还原原文;不同内容也可能碰巧得到相同结果,这叫碰撞。

  3. 3

    算法要跟使用目的匹配

    如果只是给缓存内容生成查找用的键,重点通常是速度;如果要防止有人故意伪造相同结果,就得选适合安全用途的算法。保存密码还要用专门的密码哈希方案,不能直接套用普通文件哈希。

容易混淆的地方

哈希和加密最容易混淆:加密是让持有密钥的人能解回原文,哈希通常没有“解回去”这一步。它也不是编码;编码只是换一种表示方式,通常可以还原。你看到一串字符时,先问它是用于比较内容、保密传输,还是方便存储,才能判断该选哪种方法。

什么时候用

适合用

  • 做文件上传功能时,计算上传前后的文件哈希,用来检查传输或存储过程中内容是否变化。
  • 做构建缓存时,根据源文件内容生成哈希;内容没变就复用已有结果,减少重复构建。
  • 发布安装包时,提供文件哈希供用户与下载结果比对,帮助发现文件是否损坏。

不适合用

  • 需要让授权用户重新读到原文时,比如保存可恢复的配置内容,用加密而不是哈希。
  • 只是想把二进制数据放进文本字段或接口里传输时,用合适的编码;哈希会丢失原始内容。
  • 需要按用户输入的词找到相近文章时,用搜索索引或全文检索;哈希不能判断两段文字意思是否接近。

练一练

你做了一个软件下载页,想让用户检查下载的文件是否与发布时一致。哪种方案最贴合这个目标?

让 AI 帮你做

请为网站的文件上传流程加入完整性检查:上传前后对文件内容使用同一种哈希算法计算并比对,明确哈希值在哪里生成、如何传递,以及不一致时如何提示用户。不要把哈希当作加密。

接下来学什么