百度网盘有些文件有两个 MD5?

2021-11-26 13:48:26 +08:00
 nowheretoseek

孤陋寡闻,昨天刚知道秒传油猴脚本这个东西,于是结合源码抓包研究了一下。

其基本原理可以用这篇文章嘿嘿,我发现了百度网盘秒传的秘密 - 51CTO.COM的这段话总结:

百度网盘上传时,如果是超过 256KB 的文件,将计算整个文件的 MD5 和文件前 256KB 内容的 MD5 ,并对两个 MD5 值加密后请求后端执行秒传。后端通过两个 MD5 和长度信息判断是否存在该文件,如果存在则完成秒传。

可能文章过时了,我没有发现对两个 MD5 值的加密,但发现了另一个现象,不得要领。描述如下:

百度页面提供的获取文件列表的 xhr 请求中可以看到每个文件的 MD5 (简称 MD5A ), 秒传请求中使用整个文件的 MD5 (简称 MD5B )和前 256KB 内容的 MD5 (简称 MD5C )。我发现有些文件的 MD5A 跟 MD5B 一致,有些文件的则不一致,并且这跟文件大小没有什么关系。MD5A 就是算出来哪个,而 MD5B 是从文件下载请求的响应 headers 中获取的,在 Content-MD5 字段。

所以请问,这个 MD5B 是怎么来的,怎么会跟 MD5A 不一致呢?已经有 MD5C 用来规避 MD5 碰撞了,这种设计又是为了什么?

2724 次点击
所在节点    问与答
11 条回复
kiotech
2021-11-26 14:43:26 +08:00
可能是为了优化性能,File Meta 信息生成 MD5 值 A ,文件内容生成 MD5 值 B 。文件内容相同,但修改了文件名称 /日期等 meta ,会导致 MD5 变化。
JinTianYi456
2021-11-26 15:29:44 +08:00
> 最后给大家留一个思考题:后端拿到 MD5 后,怎么判断后端是否有这个 MD5 呢? 这可是大厂经常爱考的一个面试题哦,来开动脑筋想一下!

怎么搞?有奇淫技巧?
kera0a
2021-11-26 15:42:22 +08:00
@JinTianYi456 布隆过滤器
JinTianYi456
2021-11-26 16:31:10 +08:00
@kera0a #3 感觉好像有点不对,比如后端拿到 md5 了,返回一定存在,那就秒传成功;返回 unknown ,那就开始上传,大不了多存一份呗。但如果是布隆过滤器,返回一定不存在,那就开始上传;返回 unknown ,也得上传啊。
finab
2021-11-26 17:05:44 +08:00
@JinTianYi456
我没有真的做过类似的东西,我只是简单的考虑哈~

先走布隆过滤器,返回一定不存在,至少这部分查询就已经确切完成了,不能闪存的文件就可以开始上传了(新文件和个人文件不知道占多少查询比率)查询结束。

已经上传过的文件,可以再查一个缓存,是返回一定存在或 unknown , 可以缓存热门文件之类的。

再之后就是查个人缓存或者查库或者直接传都行,这部分 上传过又不是热门的文件 量 相对来说就很少了。
selfcreditgiving
2021-11-26 17:47:29 +08:00
做过分片上传功能的就知道怎么回事了。一个大文件算 MD5 很慢的,在客户浏览器计算 md5 ,如果是 1G 文件等个 10 秒用户才看到上传进度条开始动,这个不太能接受。百度是文件头尾各取一部分内容合并起来生成“伪文件 md5”(一定程度上可以当做是一个文件的唯一 ID )。
第二个 MD5 是等大文件上传后,在后端再生成的“真文件 MD5”。
selfcreditgiving
2021-11-26 18:07:48 +08:00
@JinTianYi456 直接用 MD5 命名文件,都存到一个大文件夹,存的了就是没有,报错有同名文件就是有?

还是直接数据库插这条数据,以 MD5 字符串作为唯一索引,插不进就说明有?
nowheretoseek
2021-11-26 20:55:50 +08:00
@selfcreditgiving 有道理,我没相关经验就是参不透。所以 MD5B 即 Content-MD5 字段获取的才是完整文件的 MD5 ,MD5A 是最初上传时在客户端生成的吧
selfcreditgiving
2021-11-26 22:24:30 +08:00
@nowheretoseek

>百度页面提供的获取文件列表的 xhr 请求中可以看到每个文件的 MD5 (简称 MD5A ), 秒传请求中使用整个文件的 >MD5 (简称 MD5B )和前 256KB 内容的 MD5 (简称 MD5C )。

从这句话分析的话,肯定是秒传请求的是 客户端生成的“快速版的 MD5”。获取文件列表请求的 MD5 是真实的 文件全量 MD5
nowheretoseek
2021-11-27 01:18:59 +08:00
@selfcreditgiving 我找了个小点的文件验证,发现文件下载时从 headers 中拿到的 MD5B 是全量 MD5 ,文件列表 xhr 请求中给出 MD5A 的不是。Content-MD5 在响应头中,作为真实 MD5 ,供客户端验证下载的文件无误,也是应有之义。

根据你前面的讲解,有无可能 MD5A 是在初次上传时生成,仅作为标识符使用?总之,它在哪个环节、根据什么规则、为了什么而生成,我还是不太清楚。
nowheretoseek
2021-11-27 01:25:50 +08:00
@selfcreditgiving 提问时找了几个文件验证,正好 MD5A 与根据文件算出来的 MD5 一致,而 MDB5 要下载抓包才能知道,想当然就认为 MD5A 是全量文件的 MD5 了,已附言更正。抱歉。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/818140

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX