问答
B 站 BV 号和 AV 号是什么关系,数据库里该存哪个?
简短回答
两者是同一个视频的两种写法:BV 号由数字 aid(也就是 AV 号)经过固定的可逆编码得到,本地就能互转,不花钱。主键建议用 BV 号,链接、分享地址和 okdata 的 B站视频详情接口(每次 $0.002)用的都是它;aid 从 ext.aid 取出来另存一列,方便和老数据关联。
B 站每个视频都有一个数字编号 aid,以前的链接写成 av170001。2020 年 3 月 23 日起,链接统一换成了 BV17x411w7KC 这样的 BV 号。BV 号并不是另起炉灶的新编号,而是把 aid 套进一个固定的、可逆的编码算出来的。一个视频只对应一个 aid、一个 BV 号,两者互转几行代码就够,不用联网。
长什么样
| AV 号(aid) | BV 号(bvid) | |
|---|---|---|
| 形状 | 正整数,老链接里写成 av 加数字 |
BV1 加 9 个字符,共 12 位 |
| 字符 | 0-9 | 58 个字符的字母表,不含 0、I、O、l |
| 在哪能看到 | 老链接、评论区里的 av 号、很多旧数据集 | 现在所有链接、分享链接和 App 界面 |
| okdata 返回里 | ext.aid(需要 view=full) |
每条 B 站内容的 id |
别和 cid 搞混:cid 是多 P 视频里每一个分 P 的编号(视频详情的 ext.cid)。番剧、影视的 ep、ss 编号也是另一套。
转换算法
现行算法支持到 2^51 的 aid。编码步骤:把 aid 的第 51 位置 1,和 23442827791579 做异或,用字母表 FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf 写成 58 进制,前面加 BV1,再把第 3 位和第 9 位、第 4 位和第 7 位互换(从 0 数起)。解码把这几步倒过来做,最后用 2^51 - 1 做一次掩码。
以 av170001 为例:2^51 与 170001 按位或得 2251799813855249;再异或 23442827791579 得 2275242641642698;写成 58 进制是 7141xw7KC,拼成 BV17141xw7KC;两次互换之后就是 BV17x411w7KC。我们用同一段代码核对了 B 站热门榜上的 20 个视频,包括 15 位数的 aid,全部对得上。
该存哪个
表的主键用 BV 号。用户贴过来的、分享链接里带的、B站视频详情和 B站视频评论的 id 参数要的,都是 BV 号。需要和老数据关联时,在旁边加一列 BIGINT 存 aid。BV 号区分大小写,BV17x411w7KC 和 bv17X411W7kc 是两个不同的字符串,不要统一转小写。
| 手上有什么 | 怎么做 | 费用 |
|---|---|---|
| 一个 AV 号 | 本地转成 BV 号,再查详情 | $0.002 |
| 一个 BV 号,想要 aid | 本地转换 | 免费 |
| 搜索结果 | id 就是 BV 号,ext.aid 是 aid |
每页 $0.002 |
| 1,000 个老 aid 要刷新数据 | 先转换,再查 1,000 次 | $2.00 |
示例
XOR, MASK, TOP, BASE = 23442827791579, (1 << 51) - 1, 1 << 51, 58
ABC = "FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf"
def av_to_bv(aid: int) -> str:
n, out = (TOP | aid) ^ XOR, []
while n:
n, r = divmod(n, BASE)
out.append(ABC[r])
s = list("BV1" + "".join(reversed(out)))
s[3], s[9], s[4], s[7] = s[9], s[3], s[7], s[4]
return "".join(s)
def bv_to_av(bvid: str) -> int:
s = list(bvid)
s[3], s[9], s[4], s[7] = s[9], s[3], s[7], s[4]
n = 0
for ch in s[3:]:
n = n * BASE + ABC.index(ch)
return (n & MASK) ^ XOR
assert av_to_bv(170001) == "BV17x411w7KC" and bv_to_av("BV17x411w7KC") == 170001
想拿 B 站自己的数据核对一遍,就查一次视频详情,看它返回的 aid:
curl -G "https://api.okdata.online/v1/bilibili/videos/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=BV17x411w7KC' \
--data-urlencode 'view=full' \
--data-urlencode 'fields=id,title,ext.aid,ext.cid'
限制
- 接口接受 BV 号或
bilibili.com/video/BV...链接。av开头的链接会返回invalid_params,不扣费,先在本地转成 BV 号再传。 - 这是 B 站自己的算法,不是什么标准。哪天 B 站再改,改动之后生成的编号可能就解不开了,所以平台给你的 BV 号要原样留着,不要只存 aid。
- 过去大家查这个算法都去 bilibili-API-collect,这个仓库在 2026 年 1 月收到 B 站委托的律师函后已经关停。abv 这类小库还公开着代码。
想看 BV 号背后的播放、投币和弹幕数,见知道 BV 号,怎么拿到播放、投币和弹幕数。
资料来源
- 维基百科「哔哩哔哩」:2020 年 3 月 23 日 BV 号取代 AV 号
- Colerar/abv:B 站 AV 号与 BV 号互转函数
- yt-dlp 的 B 站提取器:同时接受 av 和 BV 前缀的视频链接
- bilibili-API-collect:2026 年 1 月停止维护并关停
这个问题出现过的地方(读取于 2026-11-12)
更新于