B站 av 号是怎么回事,bv 号怎么互转?
老 B 站用户应该记得,早年视频地址是 av10000 这种纯数字,后来全站换成了 BV1xx411c7mD 这种怪字符串。很多人好奇:bv 号看着像随机乱码,它和 av 号之间能互相算出来吗?答案是能,而且算法是公开的——只是故意搞复杂了点,防止被人轻易批量刷。
为什么要换
av 号是自增整数,等于把全站视频数量直接暴露了,也方便爬取。换成 bv 号后,表面上看不出规律,顺带还埋了一些历史彩蛋(最早一批 bv 号其实是从某个偏移量开始算的)。
bv 号的编码本质
bv 号本质是一个 Base58 编码的整数,只不过 B 站故意做了一个"异或 + 查表置换"的混淆步骤。核心思路:
- 把 bv 号去掉
BV前缀,得到 12 位字符; - 这 12 位对应一个 64 位整数,经过固定的置换表和异或处理后,得到真实的 av 号。
用 Python 互转
网上流传最广的是这段(简化版):
XOR_CODE = 23442827791579
MASK_CODE = 2251799813685247
BASE = 58
DATA = 'FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf'
def bv2av(bv):
bv = bv[2:] if bv.startswith('BV') else bv
r = 0
for i in range(6):
r += DATA.index(bv[i + 3]) * (BASE ** i)
for i in range(6):
r += DATA.index(bv[i]) * (BASE ** (i + 6))
return (r ^ XOR_CODE) - MASK_CODE - 100618342
av 转 bv 就是上面过程的逆运算,把整数重新塞回 12 位 Base58 并做反置换即可。实际项目里直接用现成库(比如 bilibili-api)更稳,别自己手写容易踩边界。
为什么还要会这个
- 有些老链接、老数据库里存的是 av 号,要对接新接口得转;
- 写脚本批量处理收藏夹时,统一成 av 号做去重更方便;
- 理解它有助于明白"为什么 bv 看着乱但能还原"。
常见问题
Q:bv 转出来的 av 号和网页显示一致吗? 一致,官方也是这套逻辑。
Q:为什么我算出来差一点? 多半是置换表抄错了,或者忘了减那个固定的偏移量,对照官方开源实现改即可。
Q:以后还会换吗? 不好说,但即便换,历史 av/bv 映射不会变,老视频照样能查。