info hash 是什么?为什么能去重
之前写 磁力链接协议解析 的时候提到过 info hash,但没有展开讲。这篇单独拎出来,因为理解了 info hash,很多磁力搜索的"玄学"就通了——比如为什么同样的电影在不同网站能搜到同一个磁力链接。
一句话定义
info hash = .torrent 文件中 info 字段的哈希值。
就这么简单。它是一个 20 字节(BTv1)或 32 字节(BTv2)的二进制串,用十六进制或 Base32 表示后嵌入磁力链接中。比如:
magnet:?xt=urn:btih:E7B7E9D4A8F1B2C5D6E7A8B9C0D1E2F3A4B5C6D7
这里面 E7B7E9D4A8F1B2C5D6E7A8B9C0D1E2F3A4B5C6D7 就是 info hash 的十六进制表示,40 个字符。
怎么算出来的
.torrent 文件内部是 bencode 编码,结构大致如下:
d
8:announce ... # tracker URL
7:comment ... # 注释
4:info # ← 这个字段
d
6:length i12345e # 文件大小
4:name 8:movie.mp4 # 文件名
12:piece length i262144e
6:pieces ... # 每个 piece 的 SHA-1
e
e
计算 info hash 的步骤:
- 从 bencode 结构中提取
info字典的原始字节(注意,要原始编码,不是重新编码后的) - 对这些字节做 SHA-1 哈希(BTv1)或 SHA-256 哈希(BTv2)
- 得到 20 字节或 32 字节的二进制结果
- 转成十六进制字符串就是磁力链接里看到的值
关键点:info 字段包含了文件列表、分块大小和每个分块的哈希值。两个 .torrent 文件哪怕其他字段完全不同,只要 info 字段一样,info hash 就一样——它们描述的是同一组文件。
为什么能去重
这是 info hash 最实用的特性。原理来自哈希函数的两个基本性质:
| 性质 | 含义 | 对去重的意义 |
|---|---|---|
| 确定性 | 相同输入 → 相同输出 | 同一内容永远产生同一个 info hash |
| 抗碰撞性 | 不同输入 → 几乎不可能相同输出 | 不同内容几乎不可能撞 hash |
实际效果:
- 电影 A 在"网站甲"和"网站乙"都被收录,但它们的 .torrent 文件不同(tracker 不同、注释不同)
- 然而它们的
info字段一样(同样的文件、同样的分块) - 所以 info hash 一样 → 可以判定为同一资源
- 磁力搜索工具(包括 磁力古哥)就能把来自不同网站的结果合并为一条
这就是为什么你在一个搜索工具里搜同一部电影不会出现几十条重复结果——底层就是在用 info hash 去重。
三种格式的兼容问题
info hash 在实际使用中有三种表示方式,经常让人困惑:
| 格式 | 长度 | 示例 |
|---|---|---|
| 十六进制(BTv1) | 40 字符 | urn:btih:E7B7E9D4... |
| Base32(BTv1) | 32 字符 | urn:btih:464362WK... |
| 十六进制(BTv2) | 64 字符 | urn:btmh:1220a1b2... |
同一个资源可以用十六进制或 Base32 两种方式表示 info hash。客户端解析时需要互相转换——Base32 解码后就是十六进制对应的二进制。我做 磁力古哥 的时候,解析模块专门处理了这个兼容逻辑。
info hash 在 BitTorrent 协议中的角色
info hash 不仅仅用于标识资源,它在协议层面扮演多个角色:
1. 握手校验
两个 BitTorrent 客户端建立 TCP 连接后,第一步握手就交换 info hash。如果双方的 info hash 不一样,直接断开——确保你连的是持有同一资源的 peer。
2. DHT 查找 key
DHT 网络(详解)用 info hash 作为 key 来查找 peer。get_peers(info_hash) 就是告诉网络:"谁有这个 info hash 的数据?"
3. Tracker announce
向 tracker 发请求时,参数里带 info hash,tracker 返回持有同一 info hash 的 peer 列表。
BTv2:SHA-256 的升级
BitTorrent v2(BEP-52)把哈希算法从 SHA-1 升级到 SHA-256。原因很简单:SHA-1 已经被认为不够安全了(虽然对 BitTorrent 场景来说碰撞攻击的风险极低)。
v2 的一个额外好处是引入了 Merkle tree 结构:每个文件的每个 16KB block 都有独立哈希。这意味着校验粒度从"整个 piece"细化到"单个 block",下载错误能更快定位。
关于 v1 和 v2 的完整对比,我另外写了一篇 BitTorrent v1 vs v2 的详细比较。