原理
上传到网盘的每个文件,服务器都会校验MD5码。如果这个您上传的文件MD5码与已经存在于服务器里的文件的MD5码相同的话,网盘服务器将会判断成为重复文件,只需要复制副本保存在网盘上即可。这样实现了服务器的高效运作。
协议分析
因此一般厂商会使用多个HASH联合的方式。 下面列出常用网盘的HASH计算方式。
Ppikpak和迅雷云盘是一个计算方式
阿里云盘之前也是SHA1和115类似
可惜的是阿里云盘前两年年取消了秒传
应用场景
本地生成秒传链接,分享或发布
网上本地生成秒传链接的工具蛮多,我自己整理了一下做了个整合版
支持115、百度网盘、pikpak,支持单个文件或文件夹
自动遍历文件夹下所有文件,生成结果保存在脚本所在txt文件
生成链接不包含路径,有需要的自己改下吧
使用方式如图
python代码和打包的exe文件放在gitee
sonata1/network-disk-application
不知道为gitee啥链接不能过审那就直接把代码打下面吧
import os
import sys
import hashlibdef get_sha1sum(buffer):
BUFFERSIZE = 128*1024
sha1 = hashlib.sha1()
sha1128ksum = None
while True:
data = buffer.read(BUFFERSIZE)
if not data:
break
sha1.update(data)
if not sha1128ksum:
sha1128ksum = hashlib.sha1(data).hexdigest().upper()
sha1sum = sha1.hexdigest().upper()
return sha1sum, sha1128ksumdef create_url(filename):
name = os.path.basename(filename)
size = os.stat(filename).st_size
with open(filename, "rb") as f:
sha1sum, sha1128ksum = get_sha1sum(f)
return "115://%s|%s|%s|%s" % (name, size, sha1sum, sha1128ksum)def gcid_hash_file(path):
h = hashlib.sha1()
size = os.path.getsize(path)
psize = 0x40000
while size / psize > 0x200 and psize < 0x200000:
psize = psize << 1
with open(path, 'rb') as stream:
data = stream.read(psize)
while data:
h.update(hashlib.sha1(data).digest())
data = stream.read(psize)
(path, filename) = os.path.split(path)return 'PikPak://'+filename+'|'+str(size)+'|'+h.hexdigest().upper()
def hash_f(pth:str,api:str='md5',block_size:int=1024*1024,head_size:int=256*1024)->list:
with open(pth,'rb') as f:
hsh=hashlib.new(api,f.read(head_size))
head=hsh.hexdigest()
while True:
data=f.read(block_size)
if not data:
break
hsh.update(data)
return [hsh.hexdigest(),head,]def _file(pth:str)->str:
if mode == 'baidu网盘':
_ll=[str(i) for i in hash_f(pth)+[os.path.getsize(pth),os.path.basename(pth)]]
ans='#'.join(_ll)
with open(mode+'_link.txt',"a+") as file: #”w"代表着每次运行都覆盖内容
file.write(ans+"n")
return os.path.abspath(pth)+' :n'+ans+'n'
if mode == 'pikpak':
ans = gcid_hash_file(pth)
with open(mode+'_link.txt',"a+") as file: #”w"代表着每次运行都覆盖内容
file.write(ans+"n")
return os.path.abspath(pth)+' :n'+ans+'n'
if mode == '115':
ans = create_url(pth)
with open(mode+'_link.txt',"a+") as file: #”w"代表着每次运行都覆盖内容
file.write(ans+"n")
return os.path.abspath(pth)+' :n'+ans+'n'def _dir(pth:str)->str:
ans=list()
for r,d,f in os.walk(pth):
for i in f:
ans.append(_file(os.path.join(r,i)))
return 'n'.join(ans)def mian(pth:str)->str:
if os.path.isfile(pth):
return _file(pth)
if os.path.isdir(pth):
return _dir(pth)
return '没有此文件或者目录: "'+os.path.abspath(pth)+'"n'sign = True #标志位置为 True
while sign:ipt = input("1:115 2:baidu网盘 3:pikpak q:退出n结果会保存在脚本所在目录对应txt文件n请输入序号:")
n = ipt
if ipt == 'q' or ipt == 'Q':
sign = False #标志位置为 False
print("Thanks for playing!")
if ipt in ['1','2','3']:
temp_list= ['115','baidu网盘','pikpak']
mode = temp_list[int(ipt)-1]
if os.path.exists(mode+'_link.txt'):
os.remove(mode+'_link.txt')
while sign:f_ipt = input("请输入要生成"+mode+"秒传链接的文件或文件夹路径:")
if f_ipt == 'q' or f_ipt == 'Q':
sign = False #标志位置为 False
else:结果 = mian(f_ipt)
print(结果)
115、百度网盘、pikpak垮网盘直接生成秒传链接
把某一家的资源迁移到另外一家
这里建议用alist配合115版rlcone挂载(不会挂载的同学可以参考系列另一篇文章)
就可以用上面的脚本生成链接了
需要注意 115和百度网盘都需要计算整个文件的HASH
也就是说相当于把文件完全下载到本地第一次
注意批量下载请求不要超过网站限制
另外还要注意传入方是否已经有这个文件了
几家网盘的体量都比较大,常规文件大部分都可以
其实做一个浏览器脚本更方便使用,不过没精力弄了
这里顺便说下国外网盘
Google Drive,Jottacloud自带MD5信息,可以免下载快速生成百度云盘秒传链接
OneDrive,Box,(还有115)自带SHA1信息,可以免下载快速生成115秒传链接
工具暂时还没写。有需要的自行google下看看能不找到
上传工具
115:油猴脚本 115转存助手
百度网盘:油猴脚本 秒传链接提取
PikPak:第三方网页版