动漫花园上,为啥同一个资源有2个磁力链接?
还有一个typeII的磁力链接,可据我所知BT的infohash是全世界唯一的2段不同的infohash为何会指向同一组资源?或者说同一个BT种子? 本帖最后由 sommio 于 2024-9-20 22:38 编辑
因为另外一个带大写字母的不是 infohash,是 base32 编码后的 infohash
❯ echo "ONK655ZLRWK2KM4VOAWZXWD7WG6XZYLZ" | base32 -d | xxd -p
7355eef72b8d95a53395702d9bd87fb1bd7ce179
另外在技术上是有产生哈希碰撞的「可能性」,说唯一其实不太严谨 本帖最后由 恋姬无双 于 2024-9-26 08:26 编辑
sommio 发表于 2024-9-20 22:34
因为另外一个带大写字母的不是 infohash,是 base32 编码后的 infohash
懂了,谢谢,你好像说反了,应该是第二个磁链里的那段小写,是这段base32的sha1码对吧
印象里磁链都是一段sha1,原来用base32也能连接到资源啊
不过这是不是多此一举,base32只有32位,比起sha1来说更容易发生碰撞吧
本帖最后由 sommio 于 2024-9-27 01:05 编辑
恋姬无双 发表于 2024-9-26 08:23
懂了,谢谢,你好像说反了,应该是第二个磁链里的那段小写,是这段base32的sha1码对吧
印象里磁链都是一段 ...
base32 不是哈希而是编码,你可以看作是压缩。
哈希不可还原,base32 只是对哈希结果(infohash)进行编码以压缩它。
base32 指的不是长度为 32 个字符,而是将任意二进制数组按 5 个分为一组映射到 32 个不同字符。
sha1 的哈希结果为 160 个二进制数(bits),一般呈现为 40 个十六进制数字符(也就是你看到的那串)。
也就是说,sha1 结果经过 base32 编码恰好为 32 个字符的原因是 160/5=32。
❯ sha1sum in.png | cut -d ' ' -f 1
e904acb15913bd32c5baac6ae0f7ce2ca0b70867
❯ sha1sum in.png | cut -d ' ' -f 1 | xxd -r -p | xxd -b
00000000: 11101001 00000100 10101100 10110001 01011001 00010011....Y.
00000006: 10111101 00110010 11000101 10111010 10101100 01101010.2...j
0000000c: 11100000 11110111 11001110 00101100 10100000 10110111...,..
00000012: 00001000 01100111 .g
❯ sha1sum in.png | cut -d ' ' -f 1 | xxd -r -p | base32
5ECKZMKZCO6TFRN2VRVOB56OFSQLOCDH
换成 sha256 就是另外一种情况了
为方便理解以下代码只截了前 60 个字符(240bits)避免出现 base32 补码
可见 base32 长度为 240/5=48 个字符
❯ sha256sum in.png | cut -d ' ' -f 1 | head -c 60
7cf3de1308645535058883992240cfe98498734289d294be5c9548d96042
❯ sha256sum in.png | cut -d ' ' -f 1 | head -c 60 | xxd -r -p | xxd -b
00000000: 01111100 11110011 11011110 00010011 00001000 01100100|....d
00000006: 01010101 00110101 00000101 10001000 10000011 10011001U5....
0000000c: 00100010 01000000 11001111 11101001 10000100 10011000"@....
00000012: 01110011 01000010 10001001 11010010 10010100 10111110sB....
00000018: 01011100 10010101 01001000 11011001 01100000 01000010\.H.`B
❯ sha256sum in.png | cut -d ' ' -f 1 | head -c 60 | xxd -r -p | base32
PTZ54EYIMRKTKBMIQOMSEQGP5GCJQ42CRHJJJPS4SVENSYCC sommio 发表于 2024-9-27 00:49
base32 不是哈希而是编码,你可以看作是压缩。
哈希不可还原,base32 只是对哈希结果(infohash)进行编 ...
原来如此,我记得infohash好像就是BT种子的info字段经过base32压缩后的sha1值对吧
但为什么还要再对这段sha1进行一次压缩呢?本身就很短了
软件解析磁链的时候还是要再把这段base32还原成sha1之后,再在DHT里搜索种子文件的吧
本帖最后由 sommio 于 2024-9-29 00:35 编辑
恋姬无双 发表于 2024-9-28 23:21
原来如此,我记得infohash好像就是BT种子的info字段经过base32压缩后的sha1值对吧
但为什么还要再对这段s ...
不是,infohash 是直接对 info 计算的 sha1 值。
无论是 info 还是 infohash 都不会使用 base32,可以看下:【译】BT下载的工作原理。
磁力链接用 base32 算是历史遗留了,见 libtorrent 作者在 stackoverflow 的回答。
(base16 指的是用 1 个 16 进制数 ascii 字符来表示 4 个二进制数的编码,sha1 计算结果实际上为 160 个二进制数)
The original magnet link format had the info-hash be base32 encoded, for space. At one point we (libtorrent and utorrent) decided it would be better to use hex (base16 encoded) for simplicity. This was probably around 2009 or 2010 iirc. However, in order to make the transition smooth, we supported reading both base32 and base16 style links (it's easy to tell the difference), but still generating base32 for backwards compatibility.
翻译 by Gemini
原始的磁力链接格式为了节省空间,将信息哈希值进行 base32 编码。后来,我们(libtorrent 和 utorrent)决定为了简化起见,最好使用十六进制(base16 编码)。如果我没记错的话,这大概是在 2009 年或 2010 年左右。然而,为了使过渡平滑,我们支持读取 base32 和 base16 两种格式的链接(很容易区分),但仍然生成 base32 格式以实现向后兼容。
sommio 发表于 2024-9-29 00:09
不是,infohash 是直接对 info 计算的 sha1 值。
无论是 info 还是 infohash 都不会使用 base32,可以看下 ...
感谢您的耐心解答,我总算搞懂了
就是还有个小小的疑问,既然一开始用的就是base32,为什么说为了简化起见而改为base16?
都是对160位的sha1编码,前者是生成32位,后者是40位,还是说这跟生成的长度无关?
本帖最后由 sommio 于 2024-9-30 04:33 编辑
恋姬无双 发表于 2024-9-30 01:08
感谢您的耐心解答,我总算搞懂了
就是还有个小小的疑问,既然一开始用的就是base32,为什么说为了简化起 ...
邮件组没翻到啥讨论,应该单纯是为了简化为简化吧。
hash 结果呈现形式为 16 个 ascii 字符用于表示十六进制基本上是惯例。
而且 base32 也基本没什么人用,用的最多就 base64
将二进制呈现为 base16/hex 单纯是为了更好阅读而已,并且跟 base32 不同单纯是惯例而非有具体规范的编码
一般「默认」hash 结果应该是可阅读的「base16/hex」,像那些泄露数据库不少都以这种形式存储 hash
屏幕上可阅读的 ascii/unicode 编码内部由二进制表示,真正的二进制 hash 结果是不可阅读的
实际上,base16/hex 将 160bit 的 sha1 hash 结果,转换为每个 8bits 共 40*8bits 的 ascii 字符以供阅读
https://assets.vviptuangou.com/2a96ea4e76951c7bbd7b5701fbad2ec9c3ab420b.jpg
表示为 base32/base16(hex) 都不重要,只要最后能正确转换回二进制就可以了,见 libtorrent 相关源码
if (value.size() == 40) aux::from_hex(value, info_hash.data());
else if (value.size() == 32)
{
std::string const ih = base32decode(value);
if (ih.size() != 20)
{
ec = errors::invalid_info_hash;
return;
}
info_hash.assign(ih);
}
else
{
ec = errors::invalid_info_hash;
return;
}
sommio 发表于 2024-9-30 03:52
邮件组没翻到啥讨论,应该单纯是为了简化为简化吧。
hash 结果呈现形式为 16 个 ascii 字符用于表示十六进 ...
明白了,再次感谢您的解答
页:
[1]