import{_ as r,c as t,a as e,e as l,w as p,r as D,o as y,b as s,d as n}from"./app-Dgsdh8A6.js";const i={};function C(d,a){const o=D("CodeGroupItem"),c=D("CodeGroup");return y(),t("div",null,[a[2]||(a[2]=e('

bvid说明

2020-03-23 B站推出了全新的稿件视频idbvid来接替之前的avid,其意义与之相同

详见:

  1. 【升级公告】AV号全面升级至BV号(专栏)
  2. 【升级公告】AV号全面升级至BV号

概述

格式

“bvid”恒为长度为 12 的字符串,前 3 个固定为“BV1”,后 9 个为 base58 计算结果(不包含数字 0 和大写字母 IO 以及小写字母 l

实质

“bvid"为“avid”的base58编码,可通过算法进行相互转化

avid发号方式的变化

从 2009-09-09 09:09:09 av2 的发布到 2020-03-28 19:45:02 av99999999 的发布B站结束了以投稿时间为顺序的avid发放,改为随机发放avid

暗示B站东方要完?泪目

算法概述

算法以及程序主要参考知乎@mcfx的回答实际上该算法并不完整,新的算法参考自【揭秘】av号转bv号的过程 实际上上面的算法依然不完整,新的算法参考自 SocialSisterYi#740来自 B 站某个 JS 文件?

av->bv算法

说明

  1. 目前的 BV 格式为 BV1XXXXXXXXX,以 BV1 开头,后面包含 9 位有效数据。
  2. AV 最大值为 2⁵¹。

算法

bv->av算法

是 #av->bv算法 的逆向

编程实现

JavaScript/TypeScript

',24)),l(c,null,{default:p(()=>[l(o,{title:"JavaScript"},{default:p(()=>a[0]||(a[0]=[s("div",{class:"language-javascript line-numbers-mode","data-highlighter":"shiki","data-ext":"javascript",style:{"background-color":"#1E1E1E",color:"#D4D4D4"}},[s("pre",{class:"shiki dark-plus vp-code"},[s("code",{class:"language-javascript"},[s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," XOR_CODE"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"23442827791579"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," MASK_CODE"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"2251799813685247"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," MAX_AID"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}}," << "),s("span",{style:{color:"#B5CEA8"}},"51"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," BASE"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"58"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," data"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#CE9178"}},"'FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf'"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"function"),s("span",{style:{color:"#DCDCAA"}}," av2bv"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"aid"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," bytes"),s("span",{style:{color:"#D4D4D4"}}," = ["),s("span",{style:{color:"#CE9178"}},"'B'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'V'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'1'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},"];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," let"),s("span",{style:{color:"#9CDCFE"}}," bvIndex"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#9CDCFE"}},"length"),s("span",{style:{color:"#D4D4D4"}}," - "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," let"),s("span",{style:{color:"#9CDCFE"}}," tmp"),s("span",{style:{color:"#D4D4D4"}}," = ("),s("span",{style:{color:"#4FC1FF"}},"MAX_AID"),s("span",{style:{color:"#D4D4D4"}}," | "),s("span",{style:{color:"#DCDCAA"}},"BigInt"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"aid"),s("span",{style:{color:"#D4D4D4"}},")) ^ "),s("span",{style:{color:"#4FC1FF"}},"XOR_CODE"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," while"),s("span",{style:{color:"#D4D4D4"}}," ("),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," > "),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#9CDCFE"}},"bvIndex"),s("span",{style:{color:"#D4D4D4"}},"] = "),s("span",{style:{color:"#9CDCFE"}},"data"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#DCDCAA"}},"Number"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," % "),s("span",{style:{color:"#DCDCAA"}},"BigInt"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#4FC1FF"}},"BASE"),s("span",{style:{color:"#D4D4D4"}},"))];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," tmp"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," / "),s("span",{style:{color:"#4FC1FF"}},"BASE"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," bvIndex"),s("span",{style:{color:"#D4D4D4"}}," -= "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," }")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#9CDCFE"}}," bytes"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"join"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"''"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"function"),s("span",{style:{color:"#DCDCAA"}}," bv2av"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"bvid"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," bvidArr"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"Array"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"from"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"bvid"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," bvidArr"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"splice"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," tmp"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"reduce"),s("span",{style:{color:"#D4D4D4"}},"(("),s("span",{style:{color:"#9CDCFE"}},"pre"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"bvidChar"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#569CD6"}},"=>"),s("span",{style:{color:"#9CDCFE"}}," pre"),s("span",{style:{color:"#D4D4D4"}}," * "),s("span",{style:{color:"#4FC1FF"}},"BASE"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#DCDCAA"}},"BigInt"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"data"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"indexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"bvidChar"),s("span",{style:{color:"#D4D4D4"}},")), "),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#DCDCAA"}}," Number"),s("span",{style:{color:"#D4D4D4"}},"(("),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," & "),s("span",{style:{color:"#4FC1FF"}},"MASK_CODE"),s("span",{style:{color:"#D4D4D4"}},") ^ "),s("span",{style:{color:"#4FC1FF"}},"XOR_CODE"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}},"console"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"log"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#DCDCAA"}},"av2bv"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#B5CEA8"}},"111298867365120"),s("span",{style:{color:"#D4D4D4"}},"));")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}},"console"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"log"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#DCDCAA"}},"bv2av"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'BV1L9Uoa9EUx'"),s("span",{style:{color:"#D4D4D4"}},"));")])])]),s("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"})])],-1)])),_:1,__:[0]}),l(o,{title:"TypeScript"},{default:p(()=>a[1]||(a[1]=[s("div",{class:"language-typescript line-numbers-mode","data-highlighter":"shiki","data-ext":"typescript",style:{"background-color":"#1E1E1E",color:"#D4D4D4"}},[s("pre",{class:"shiki dark-plus vp-code"},[s("code",{class:"language-typescript"},[s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," XOR_CODE"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"23442827791579"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," MASK_CODE"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"2251799813685247"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," MAX_AID"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}}," << "),s("span",{style:{color:"#B5CEA8"}},"51"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," BASE"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#B5CEA8"}},"58"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"const"),s("span",{style:{color:"#4FC1FF"}}," data"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#CE9178"}},"'FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf'"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"function"),s("span",{style:{color:"#DCDCAA"}}," av2bv"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"aid"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#4EC9B0"}},"number"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," bytes"),s("span",{style:{color:"#D4D4D4"}}," = ["),s("span",{style:{color:"#CE9178"}},"'B'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'V'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'1'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#CE9178"}},"'0'"),s("span",{style:{color:"#D4D4D4"}},"];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," let"),s("span",{style:{color:"#9CDCFE"}}," bvIndex"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#9CDCFE"}},"length"),s("span",{style:{color:"#D4D4D4"}}," - "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," let"),s("span",{style:{color:"#9CDCFE"}}," tmp"),s("span",{style:{color:"#D4D4D4"}}," = ("),s("span",{style:{color:"#4FC1FF"}},"MAX_AID"),s("span",{style:{color:"#D4D4D4"}}," | "),s("span",{style:{color:"#DCDCAA"}},"BigInt"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"aid"),s("span",{style:{color:"#D4D4D4"}},")) ^ "),s("span",{style:{color:"#4FC1FF"}},"XOR_CODE"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," while"),s("span",{style:{color:"#D4D4D4"}}," ("),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," > "),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#9CDCFE"}},"bvIndex"),s("span",{style:{color:"#D4D4D4"}},"] = "),s("span",{style:{color:"#9CDCFE"}},"data"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#DCDCAA"}},"Number"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," % "),s("span",{style:{color:"#DCDCAA"}},"BigInt"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#4FC1FF"}},"BASE"),s("span",{style:{color:"#D4D4D4"}},"))];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," tmp"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," / "),s("span",{style:{color:"#4FC1FF"}},"BASE"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," bvIndex"),s("span",{style:{color:"#D4D4D4"}}," -= "),s("span",{style:{color:"#B5CEA8"}},"1"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," }")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bytes"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#9CDCFE"}}," bytes"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"join"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"''"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#C586C0"}},"as"),s("span",{style:{color:"#CE9178"}}," `BV1"),s("span",{style:{color:"#569CD6"}},"${"),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#569CD6"}},"}"),s("span",{style:{color:"#CE9178"}},"`"),s("span",{style:{color:"#D4D4D4"}},";")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}},"function"),s("span",{style:{color:"#DCDCAA"}}," bv2av"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"bvid"),s("span",{style:{color:"#D4D4D4"}},": "),s("span",{style:{color:"#CE9178"}},"`BV1"),s("span",{style:{color:"#569CD6"}},"${"),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#569CD6"}},"}"),s("span",{style:{color:"#CE9178"}},"`"),s("span",{style:{color:"#D4D4D4"}},") {")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," bvidArr"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"Array"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"from"),s("span",{style:{color:"#D4D4D4"}},"<"),s("span",{style:{color:"#4EC9B0"}},"string"),s("span",{style:{color:"#D4D4D4"}},">("),s("span",{style:{color:"#9CDCFE"}},"bvid"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"9"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}}," ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"]] = ["),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"7"),s("span",{style:{color:"#D4D4D4"}},"], "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"["),s("span",{style:{color:"#B5CEA8"}},"4"),s("span",{style:{color:"#D4D4D4"}},"]];")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}}," bvidArr"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"splice"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#B5CEA8"}},"3"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#569CD6"}}," const"),s("span",{style:{color:"#4FC1FF"}}," tmp"),s("span",{style:{color:"#D4D4D4"}}," = "),s("span",{style:{color:"#9CDCFE"}},"bvidArr"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"reduce"),s("span",{style:{color:"#D4D4D4"}},"(("),s("span",{style:{color:"#9CDCFE"}},"pre"),s("span",{style:{color:"#D4D4D4"}},", "),s("span",{style:{color:"#9CDCFE"}},"bvidChar"),s("span",{style:{color:"#D4D4D4"}},") "),s("span",{style:{color:"#569CD6"}},"=>"),s("span",{style:{color:"#9CDCFE"}}," pre"),s("span",{style:{color:"#D4D4D4"}}," * "),s("span",{style:{color:"#4FC1FF"}},"BASE"),s("span",{style:{color:"#D4D4D4"}}," + "),s("span",{style:{color:"#DCDCAA"}},"BigInt"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"data"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"indexOf"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#9CDCFE"}},"bvidChar"),s("span",{style:{color:"#D4D4D4"}},")), "),s("span",{style:{color:"#B5CEA8"}},"0"),s("span",{style:{color:"#569CD6"}},"n"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#C586C0"}}," return"),s("span",{style:{color:"#DCDCAA"}}," Number"),s("span",{style:{color:"#D4D4D4"}},"(("),s("span",{style:{color:"#9CDCFE"}},"tmp"),s("span",{style:{color:"#D4D4D4"}}," & "),s("span",{style:{color:"#4FC1FF"}},"MASK_CODE"),s("span",{style:{color:"#D4D4D4"}},") ^ "),s("span",{style:{color:"#4FC1FF"}},"XOR_CODE"),s("span",{style:{color:"#D4D4D4"}},");")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#D4D4D4"}},"}")]),n(` `),s("span",{class:"line"}),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}},"console"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"log"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#DCDCAA"}},"av2bv"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#B5CEA8"}},"111298867365120"),s("span",{style:{color:"#D4D4D4"}},"));")]),n(` `),s("span",{class:"line"},[s("span",{style:{color:"#9CDCFE"}},"console"),s("span",{style:{color:"#D4D4D4"}},"."),s("span",{style:{color:"#DCDCAA"}},"log"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#DCDCAA"}},"bv2av"),s("span",{style:{color:"#D4D4D4"}},"("),s("span",{style:{color:"#CE9178"}},"'BV1L9Uoa9EUx'"),s("span",{style:{color:"#D4D4D4"}},"));")])])]),s("div",{class:"line-numbers","aria-hidden":"true",style:{"counter-reset":"line-number 0"}},[s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"}),s("div",{class:"line-number"})])],-1)])),_:1,__:[1]})]),_:1}),a[3]||(a[3]=e(`

Python

来自:#847

XOR_CODE = 23442827791579
MASK_CODE = 2251799813685247
MAX_AID = 1 << 51
ALPHABET = "FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf"
ENCODE_MAP = 8, 7, 0, 5, 1, 3, 2, 4, 6
DECODE_MAP = tuple(reversed(ENCODE_MAP))

BASE = len(ALPHABET)
PREFIX = "BV1"
PREFIX_LEN = len(PREFIX)
CODE_LEN = len(ENCODE_MAP)

def av2bv(aid: int) -> str:
    bvid = [""] * 9
    tmp = (MAX_AID | aid) ^ XOR_CODE
    for i in range(CODE_LEN):
        bvid[ENCODE_MAP[i]] = ALPHABET[tmp % BASE]
        tmp //= BASE
    return PREFIX + "".join(bvid)

def bv2av(bvid: str) -> int:
    assert bvid[:3] == PREFIX

    bvid = bvid[3:]
    tmp = 0
    for i in range(CODE_LEN):
        idx = ALPHABET.index(bvid[DECODE_MAP[i]])
        tmp = tmp * BASE + idx
    return (tmp & MASK_CODE) ^ XOR_CODE

assert av2bv(111298867365120) == "BV1L9Uoa9EUx"
assert bv2av("BV1L9Uoa9EUx") == 111298867365120

Rust

参考 https://github.com/Colerar/abv/blob/main/src/lib.rs

Swift

fileprivate let XOR_CODE: UInt64 = 23442827791579
fileprivate let MASK_CODE: UInt64 = 2251799813685247
fileprivate let MAX_AID: UInt64 = 1 << 51

fileprivate let data: [UInt8] = [70, 99, 119, 65, 80, 78, 75, 84, 77, 117, 103, 51, 71, 86, 53, 76, 106, 55, 69, 74, 110, 72, 112, 87, 115, 120, 52, 116, 98, 56, 104, 97, 89, 101, 118, 105, 113, 66, 122, 54, 114, 107, 67, 121, 49, 50, 109, 85, 83, 68, 81, 88, 57, 82, 100, 111, 90, 102]

fileprivate let BASE: UInt64 = 58
fileprivate let BV_LEN: Int = 12
fileprivate let PREFIX: String = "BV1"

func av2bv(avid: UInt64) -> String {
    var bytes: [UInt8] = [66, 86, 49, 48, 48, 48, 48, 48, 48, 48, 48, 48]
    var bvIdx = BV_LEN - 1
    var tmp = (MAX_AID | avid) ^ XOR_CODE

    while tmp != 0 {
        bytes[bvIdx] = data[Int(tmp % BASE)]
        tmp /= BASE
        bvIdx -= 1
    }

    bytes.swapAt(3, 9)
    bytes.swapAt(4, 7)

    return String(decoding: bytes, as: UTF8.self)
}

func bv2av(bvid: String) -> UInt64 {
    let fixedBvid: String
    if bvid.hasPrefix("BV") {
        fixedBvid = bvid
    } else {
        fixedBvid = "BV" + bvid
    }
    var bvidArray = Array(fixedBvid.utf8)

    bvidArray.swapAt(3, 9)
    bvidArray.swapAt(4, 7)

    let trimmedBvid = String(decoding: bvidArray[3...], as: UTF8.self)

    var tmp: UInt64 = 0

    for char in trimmedBvid {
        if let idx = data.firstIndex(of: char.utf8.first!) {
            tmp = tmp * BASE + UInt64(idx)
        }
    }

    return (tmp & MASK_CODE) ^ XOR_CODE
}

print(av2bv(avid: 111298867365120))
print(bv2av(bvid: "BV1L9Uoa9EUx"))

Java

import java.math.BigInteger;

/**
 * @author cctyl
 */
public class AVBVConverter {

    private static final BigInteger XOR_CODE = BigInteger.valueOf(23442827791579L);
    private static final BigInteger MASK_CODE = BigInteger.valueOf(2251799813685247L);
    private static final BigInteger MAX_AID = BigInteger.ONE.shiftLeft(51);
    private static final int BASE = 58;

    private static final String DATA = "FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf";

    public static String av2bv(long aidParam) {
        BigInteger aid = BigInteger.valueOf(aidParam);
        char[] bytes = {'B', 'V', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
        int bvIndex = bytes.length - 1;
        BigInteger tmp = MAX_AID.or(aid).xor(XOR_CODE);
        while (tmp.compareTo(BigInteger.ZERO) > 0) {
            bytes[bvIndex] = DATA.charAt(tmp.mod(BigInteger.valueOf(BASE)).intValue());
            tmp = tmp.divide(BigInteger.valueOf(BASE));
            bvIndex--;
        }
        swap(bytes, 3, 9);
        swap(bytes, 4, 7);
        return new String(bytes);
    }

    public static long bv2av(String bvid) {
        char[] bvidArr = bvid.toCharArray();
        swap(bvidArr, 3, 9);
        swap(bvidArr, 4, 7);
        String adjustedBvid = new String(bvidArr, 3, bvidArr.length - 3);
        BigInteger tmp = BigInteger.ZERO;
        for (char c : adjustedBvid.toCharArray()) {
            tmp = tmp.multiply(BigInteger.valueOf(BASE)).add(BigInteger.valueOf(DATA.indexOf(c)));
        }
        BigInteger xor = tmp.and(MASK_CODE).xor(XOR_CODE);
        return xor.longValue();
    }


    private static void swap(char[] array, int i, int j) {
        char temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public static void main(String[] args) {

        final int aid1 = 643755790;
        final String bv1 = "BV1bY4y1j7RA";

        final int aid2 = 305988942;
        final String bv2 = "BV1aP411K7it";

        //av ==> bv
        assert av2bv(aid1).equals(bv1);
        assert av2bv(aid2).equals(bv2);

        //bv ==>av
        assert bv2av(bv1) == aid1;
        assert bv2av(bv2) == aid2;
    }
}

Golang

package main

import (
	"fmt"
	"strings"
)

var (
	XOR_CODE = int64(23442827791579)
	MAX_CODE = int64(2251799813685247)
	CHARTS   = "FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf"
	PAUL_NUM = int64(58)
)

func swapString(s string, x, y int) string {
	chars := []rune(s)
	chars[x], chars[y] = chars[y], chars[x]
	return string(chars)
}

func Bvid2Avid(bvid string) (avid int64) {
	s := swapString(swapString(bvid, 3, 9), 4, 7)
	bv1 := string([]rune(s)[3:])
	temp := int64(0)
	for _, c := range bv1 {
		idx := strings.IndexRune(CHARTS, c)
		temp = temp*PAUL_NUM + int64(idx)
	}
	avid = (temp & MAX_CODE) ^ XOR_CODE
	return
}

func Avid2Bvid(avid int64) (bvid string) {
	arr := [12]string{"B", "V", "1"}
	bvIdx := len(arr) - 1
	temp := (avid | (MAX_CODE + 1)) ^ XOR_CODE
	for temp > 0 {
		idx := temp % PAUL_NUM
		arr[bvIdx] = string(CHARTS[idx])
		temp /= PAUL_NUM
		bvIdx--
	}
	raw := strings.Join(arr[:], "")
	bvid = swapString(swapString(raw, 3, 9), 4, 7)
	return
}

func main() {
	avid := int64(1054803170)
	bvid := "BV1mH4y1u7UA"
	resAvid := Bvid2Avid(bvid)
	resBvid := Avid2Bvid(avid)

	fmt.Printf("convert bvid to avid: %v\\tvalue:%v\\n", avid == resAvid, resAvid)
	fmt.Printf("convert avid to bvid: %v\\tvalue:%v\\n", bvid == resBvid, resBvid)

}

C++

#include <algorithm>
#include <cassert>
#include <print>
#include <string>

constexpr int64_t XOR_CODE          = 0x1552356C4CDB;
constexpr int64_t MAX_AID           = 0x8000000000000;
constexpr int64_t MASK_CODE         = MAX_AID - 1;
constexpr int64_t BASE              = 58;
constexpr char    Table[BASE + 1]   = "FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf";
constexpr char    ReverseTable[128] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x2c, 0x2d, 0x0b, 0x1a, 0x0e, 0x27, 0x11, 0x1d, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x03, 0x25, 0x2a, 0x31, 0x12, 0x00, 0x0c, 0x15, 0x00, 0x13, 0x06, 0x0f, 0x08, 0x05, 0x00,
    0x04, 0x32, 0x35, 0x30, 0x07, 0x2f, 0x0d, 0x17, 0x33, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x1f, 0x1c, 0x01, 0x36, 0x21, 0x39, 0x0a, 0x1e, 0x23, 0x10, 0x29, 0x00, 0x2e, 0x14, 0x37,
    0x16, 0x24, 0x28, 0x18, 0x1b, 0x09, 0x22, 0x02, 0x19, 0x2b, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00
};

std::string Av2bv(const int64_t Avid) {
    assert(Avid > 0 && "Avid must be greater than 0");
    std::string bv = "BV1";
    bv.resize(12, '\\0');

    int64_t tmp = (Avid | MAX_AID) ^ XOR_CODE;
    for (size_t i = bv.size() - 1; tmp > 0 && i > 2; --i) {
        bv[i] = Table[tmp % BASE];
        tmp /= BASE;
    }
    std::ranges::swap(bv.at(3), bv.at(9));
    std::ranges::swap(bv.at(4), bv.at(7));
    return bv;
}

int64_t Bv2av(const std::string &Bvid) {
    assert(Bvid.starts_with("BV1") && "Bvid must start with 'BV1'");

    auto Bvid_ = Bvid;
    std::ranges::swap(Bvid_.at(3), Bvid_.at(9));
    std::ranges::swap(Bvid_.at(4), Bvid_.at(7));

    int64_t tmp = 0;
    for (int i = 3; i < Bvid_.size(); ++i) {
        tmp = ReverseTable[Bvid_.at(i)] + BASE * tmp;
    }
    return (tmp & MASK_CODE) ^ XOR_CODE;
}

int main() {
    assert(Av2bv(1004871019) == "BV16x4y1H7M1");
    assert(Bv2av("BV16x4y1H7M1") == 1004871019);
}

老版算法存档

以下算法已失效,编解码函数值域有限,不推荐使用,在此仅作为存档

查看折叠内容:

算法参考自【揭秘】av号转bv号的过程

av->bv算法

注:本算法及示例程序仅能编解码avid < 29460791296,且暂无法验证avid >= 29460791296的正确性 再注:本人不清楚新算法能否编解码avid >= 29460791296

  1. a = (avid ⊕ 177451812) + 100618342136696320
  2. 以 i 为循环变量循环 6 次 b[i] = (a / 58 ^ i) % 58
  3. 将 b[i] 中各个数字转换为以下码表中的字符

码表:

fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF

  1. 初始化字符串 b[i]=

  2. 按照以下字符顺序编码表编码并填充至 b[i]

字符顺序编码表:

0 -> 9

1 -> 8

2 -> 1

3 -> 6

4 -> 2

5 -> 4

6 -> 0

7 -> 7

8 -> 3

9 -> 5

bv->av算法

为以上算法的逆运算

编程实现

使用 Python C TypeScript Java Kotlin Golang Rust 等语言作为示例,欢迎社区提交更多例程

Python

XOR = 177451812
ADD = 100618342136696320
TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"
MAP = 9, 8, 1, 6, 2, 4, 0, 7, 3, 5


def av2bv(av: int) -> str:
    av = (av ^ XOR) + ADD
    bv = [""] * 10
    for i in range(10):
        bv[MAP[i]] = TABLE[(av // 58**i) % 58]
    return "".join(bv)


def bv2av(bv: int) -> int:
    av = [""] * 10
    s = 0
    for i in range(10):
        s += TABLE.find(bv[MAP[i]]) * 58**i
    av = (s - ADD) ^ XOR

    return av


def main():
    while 1:
        mode = input("1. AV to BV\\n2. BV to AV\\n3. Exit\\n你的选择:")
        if mode == "1":
            print(f"BV号是:BV {av2bv(int(input('AV号是:')))}")
        elif mode == "2":
            print(f"AV号是:AV {bv2av(input('BV号是:'))}")
        elif mode == "3":
            break
        else:
            print("输入错误请重新输入")


if __name__ == "__main__":
    main()

C

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

const char table[] = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"; // 码表
char tr[124]; // 反查码表
const unsigned long long XOR = 177451812; // 固定异或值
const unsigned long long ADD = 8728348608; // 固定加法值
const int s[] = {11, 10, 3, 8, 4, 6}; // 位置编码表

// 初始化反查码表
void tr_init() {
	for (int i = 0; i < 58; i++)
		tr[table[i]] = i;
}

unsigned long long bv2av(char bv[]) {
	unsigned long long r = 0;
	unsigned long long av;
	for (int i = 0; i < 6; i++)
		r += tr[bv[s[i]]] * (unsigned long long)pow(58, i);
	av = (r - ADD) ^ XOR;
	return av;
}

char *av2bv(unsigned long long av) {
	char *result = (char*)malloc(13);
	strcpy(result,"BV1  4 1 7  ");
	av = (av ^ XOR) + ADD;
	for (int i = 0; i < 6; i++)
		result[s[i]] = table[(unsigned long long)(av / (unsigned long long)pow(58, i)) % 58];
	return result;
}

int main() {
	tr_init();
	printf("%s\\n", av2bv(170001));
	printf("%u\\n", bv2av("BV17x411w7KC"));
	return 0;
}

输出为:

BV17x411w7KC
170001

TypeScript

感谢#417提供

export default class BvCode {
  private TABEL = 'fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF'; // 码表
  private TR: Record<string, number> = {}; // 反查码表
  private S = [11, 10, 3, 8, 4, 6]; // 位置编码表
  private XOR = 177451812; // 固定异或值
  private ADD = 8728348608; // 固定加法值
  constructor() {
    // 初始化反查码表
    const len = this.TABEL.length;
    for (let i = 0; i < len; i++) {
      this.TR[this.TABEL[i]] = i;
    }
  }
  av2bv(av: number): string {
    const x_ = (av ^ this.XOR) + this.ADD;
    const r = ['B', 'V', '1', , , '4', , '1', , '7'];
    for (let i = 0; i < 6; i++) {
      r[this.S[i]] = this.TABEL[Math.floor(x_ / 58 ** i) % 58];
    }
    return r.join('');
  }
  bv2av(bv: string): number {
    let r = 0;
    for (let i = 0; i < 6; i++) {
      r += this.TR[bv[this.S[i]]] * 58 ** i;
    }
    return (r - this.ADD) ^ this.XOR;
  }
}

const bvcode = new BvCode();

console.log(bvcode.av2bv(170001));
console.log(bvcode.bv2av('BV17x411w7KC'));

输出为:

BV17x411w7KC
170001

Java

/**
 * 算法来自:https://www.zhihu.com/question/381784377/answer/1099438784
 */
public class Util {
    private static final String TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
    private static final int[] S = new int[]{11, 10, 3, 8, 4, 6};
    private static final int XOR = 177451812;
    private static final long ADD = 8728348608L;
    private static final Map<Character, Integer> MAP = new HashMap<>();

    static {
        for (int i = 0; i < 58; i++) {
            MAP.put(TABLE.charAt(i), i);
        }
    }

    public static String aidToBvid(int aid) {
        long x = (aid ^ XOR) + ADD;
        char[] chars = new char[]{'B', 'V', '1', ' ', ' ', '4', ' ', '1', ' ', '7', ' ', ' '};
        for (int i = 0; i < 6; i++) {
            int pow = (int) Math.pow(58, i);
            long i1 = x / pow;
            int index = (int) (i1 % 58);
            chars[S[i]] = TABLE.charAt(index);
        }
        return String.valueOf(chars);
    }

    public static int bvidToAid(String bvid) {
        long r = 0;
        for (int i = 0; i < 6; i++) {
            r += MAP.get(bvid.charAt(S[i])) * Math.pow(58, i);
        }
        return (int) ((r - ADD) ^ XOR);
    }
}

Kotlin

/**
 * 此程序非完全原创,改编自GH站内某大佬的Java程序,修改了部分代码,且转换为Kotlin
 * 算法来源同上
 */
object VideoUtils {
    //这里是由知乎大佬不知道用什么方法得出的转换用数字
    var ss = intArrayOf(11, 10, 3, 8, 4, 6, 2, 9, 5, 7)
    var xor: Long = 177451812 //二进制时加减数1

    var add = 8728348608L //十进制时加减数2

    //变量初始化工作,加载哈希表
    private const val table = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"
    private val mp = HashMap<String, Int>()
    private val mp2 = HashMap<Int, String>()

    //现在,定义av号和bv号互转的方法
//定义一个power乘方方法,这是转换进制必要的
    fun power(a: Int, b: Int): Long {
        var power: Long = 1
        for (c in 0 until b) power *= a.toLong()
        return power
    }

    //bv转av方法
    fun bv2av(s: String): String {
        var r: Long = 0
        //58进制转换
        for (i in 0..57) {
            val s1 = table.substring(i, i + 1)
            mp[s1] = i
        }
        for (i in 0..5) {
            r += mp[s.substring(ss[i], ss[i] + 1)]!! * power(58, i)
        }
        //转换完成后,需要处理,带上两个随机数
        return (r - add xor xor).toString()
    }

    //av转bv方法
    fun av2bv(st: String): String {
        try {
            var s = java.lang.Long.valueOf(st.split("av".toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray()[1])
            val sb = StringBuffer("BV1  4 1 7  ")
            //逆向思路,先将随机数还原
            s = (s xor xor) + add
            //58进制转回
            for (i in 0..57) {
                val s1 = table.substring(i, i + 1)
                mp2[i] = s1
            }
            for (i in 0..5) {
                val r = mp2[(s / power(58, i) % 58).toInt()]
                sb.replace(ss[i], ss[i] + 1, r!!)
            }
            return sb.toString()
        } catch (e: ArrayIndexOutOfBoundsException) {
            return ""
        }
    }

}

Golang

package main

import "math"

const TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF"
var S = [11]uint{11, 10, 3, 8, 4, 6}
const XOR = 177451812
const ADD = 8728348608

var TR = map[string]int64{}

// 初始化 TR
func init() {
	for i := 0; i < 58; i++ {
		TR[TABLE[i:i+1]] = int64(i)
	}
}

func BV2AV(bv string) int64 {
	r := int64(0)
	for i := 0; i < 6; i++ {
		r += TR[bv[S[i]:S[i]+1]] * int64(math.Pow(58, float64(i)))
	}
	return (r - ADD) ^ XOR
}

func AV2BV(av int64) string {
	x := (av ^ XOR) + ADD
	r := []rune("BV1  4 1 7  ")
	for i := 0; i < 6; i++ {
		r[S[i]] = rune(TABLE[x/int64(math.Pow(58, float64(i)))%58])
	}
	return string(r)
}

func main() {
	println(AV2BV(170001))
	println(BV2AV("BV17x411w7KC"))
}

输出为:

BV17x411w7KC
170001

Rust

crate: https://github.com/stackinspector/bvid

// Copyright (c) 2023 stackinspector. MIT license.

const XORN: u64 = 177451812;
const ADDN: u64 = 100618342136696320;
const TABLE: [u8; 58] = *b"fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
const MAP: [usize; 10] = [9, 8, 1, 6, 2, 4, 0, 7, 3, 5];
const REV_TABLE: [u8; 74] = [
    13, 12, 46, 31, 43, 18, 40, 28,  5,  0,  0,  0,  0,  0,  0,  0, 54, 20, 15, 8,
    39, 57, 45, 36,  0, 38, 51, 42, 49, 52,  0, 53,  7,  4,  9, 50, 10, 44, 34, 6,
    25,  1,  0,  0,  0,  0,  0,  0, 26, 29, 56,  3, 24,  0, 47, 27, 22, 41, 16, 0,
    11, 37,  2, 35, 21, 17, 33, 30, 48, 23, 55, 32, 14, 19,
];
const POW58: [u64; 10] = [
    1, 58, 3364, 195112, 11316496, 656356768, 38068692544,
    2207984167552, 128063081718016, 7427658739644928,
];

fn av2bv(avid: u64) -> [u8; 10] {
    let a = (avid ^ XORN) + ADDN;
    let mut bvid = [0; 10];
    for i in 0..10 {
        bvid[MAP[i]] = TABLE[(a / POW58[i]) as usize % 58];
    }
    bvid
}

fn bv2av(bvid: [u8; 10]) -> u64 {
    let mut a = 0;
    for i in 0..10 {
        a += REV_TABLE[bvid[MAP[i]] as usize - 49] as u64 * POW58[i];
    }
    (a - ADDN) ^ XORN
}

// assert_eq!(*b"17x411w7KC", av2bv(170001));
// assert_eq!(170001, bv2av(*b"17x411w7KC"));
`,16))])}const E=r(i,[["render",C]]),A=JSON.parse('{"path":"/docs/misc/bvid_desc.html","title":"bvid说明","lang":"zh-CN","frontmatter":{},"git":{"updatedTime":1745082190000,"contributors":[{"name":"SocialSisterYi","username":"SocialSisterYi","email":"1440239038@qq.com","commits":4,"url":"https://github.com/SocialSisterYi"},{"name":"zine0","username":"zine0","email":"46991452+zine0@users.noreply.github.com","commits":1,"url":"https://github.com/zine0"},{"name":"stackinspector","username":"stackinspector","email":"stackinspector@126.com","commits":2,"url":"https://github.com/stackinspector"},{"name":"EvanHsieh0415","username":"EvanHsieh0415","email":"74277414+EvanHsieh0415@users.noreply.github.com","commits":1,"url":"https://github.com/EvanHsieh0415"},{"name":"Kataick","username":"Kataick","email":"24969684+Kataick@users.noreply.github.com","commits":2,"url":"https://github.com/Kataick"},{"name":"LaMerChiang","username":"LaMerChiang","email":"catlair@qq.com","commits":2,"url":"https://github.com/LaMerChiang"},{"name":"WindowsMEMZ","username":"WindowsMEMZ","email":"45706356+WindowsMEMZ@users.noreply.github.com","commits":1,"url":"https://github.com/WindowsMEMZ"},{"name":"F-park","username":"F-park","email":"52167622+F-park@users.noreply.github.com","commits":1,"url":"https://github.com/F-park"},{"name":"GalaxySnail","username":"GalaxySnail","email":"me@glxys.nl","commits":4,"url":"https://github.com/GalaxySnail"},{"name":"cctyl","username":"cctyl","email":"34262992+cctyl@users.noreply.github.com","commits":1,"url":"https://github.com/cctyl"},{"name":"YuHuanTin","username":"YuHuanTin","email":"51024916+YuHuanTin@users.noreply.github.com","commits":1,"url":"https://github.com/YuHuanTin"},{"name":"WShihan","username":"WShihan","email":"52617949+WShihan@users.noreply.github.com","commits":1,"url":"https://github.com/WShihan"},{"name":"wsh","username":"wsh","email":"3443327820@qq.com","commits":1,"url":"https://github.com/wsh"},{"name":"SessionHu","username":"SessionHu","email":"102411014+SessionHu@users.noreply.github.com","commits":2,"url":"https://github.com/SessionHu"}],"changelog":[{"hash":"ea76fb00e62ee9a486ee010e67d73a133ba9b7af","time":1745082190000,"email":"102411014+SessionHu@users.noreply.github.com","author":"SessionHu","message":"fix(misc/bvid_desc.md): cpp highlight & remove old links"},{"hash":"18c1efbc102ae6b44c8f5314c90e5e64f0d926cd","time":1721909032000,"email":"102411014+SessionHu@users.noreply.github.com","author":"Session小胡","message":"feat: bili_ticket 算法 Java 实现 及 信息补充 及 错误修正 (#1061)"},{"hash":"ce07d83125fa265810272867211bbc16f9a85ff2","time":1718806390000,"email":"52617949+WShihan@users.noreply.github.com","author":"wsh","message":"feat: bv<-->av algo implemented in golang (#1027)","coAuthors":[{"name":"wsh","email":"3443327820@qq.com"}]},{"hash":"e7ab2d770b423a891ed7e663d94bfe1f0f59501d","time":1718245563000,"email":"51024916+YuHuanTin@users.noreply.github.com","author":"YuHuanTin","message":"wbi、av2bv、bv2av 的 c++ 实现 (#1035)"},{"hash":"11d42851ae07fd95f8af37a354c672f07f999ad2","time":1716219747000,"email":"34262992+cctyl@users.noreply.github.com","author":"cctyl","message":"feat: bv<-->av 增加java实现 (#1021)"},{"hash":"7b22c145d25f3ad725fce78c525254ebe60cf673","time":1707387835000,"email":"me@glxys.nl","author":"GalaxySnail","message":"docs/misc/bvid_desc.md: 不需要将 bvid 转换为 list"},{"hash":"3387e547bbd1d9b60ecebaeb542d6bce0bbb314f","time":1707387424000,"email":"me@glxys.nl","author":"GalaxySnail","message":"docs/misc/bvid_desc.md: 使用整数除法代替浮点数除法"},{"hash":"6fd4109cc0fee441271d664d53449e7849333639","time":1707387324000,"email":"me@glxys.nl","author":"GalaxySnail","message":"docs/misc/bvid_desc.md: 删除未使用的 BV_LEN 变量"},{"hash":"a53d158ee6e1422e85bb1f3197e887242da6227d","time":1707387257000,"email":"me@glxys.nl","author":"GalaxySnail","message":"docs/misc/bvid_desc.md: 删除多余的行尾空格"},{"hash":"33bde6f6afcac2ff8c6f7069f08ce84065a6cff6","time":1707041879000,"email":"1440239038@qq.com","author":"SocialSisterYi","message":"Update av2bv Python Demo"},{"hash":"f16cfe9793d233c81a006c1b5ac907905cea38ff","time":1706768036000,"email":"24969684+Kataick@users.noreply.github.com","author":"Kataick","message":"规范bv转av(python)示例的类型 (#960)"},{"hash":"1045da3751a8a5916fb2b3428ad902c4d4e14115","time":1704755026000,"email":"52167622+F-park@users.noreply.github.com","author":"F-park","message":"fix typo in bvid_desc.md (#928)"},{"hash":"27308c22c83e14bb67ac39425574dfbe32aa0b89","time":1702173833000,"email":"45706356+WindowsMEMZ@users.noreply.github.com","author":"Mark Chan","message":"为avid-bvid转换和Wbi签名添加Swift实现 (#890)"},{"hash":"507f20e88df2a5a0ba8c2bb980a1523e29dcf8d2","time":1700364910000,"email":"catlair@qq.com","author":"LaMerChiang","message":"更新 bvid 算法 (#862)"},{"hash":"6430bffbd66dbd6051bd420cd066ec8976a85452","time":1700098532000,"email":"catlair@qq.com","author":"LaMerChiang","message":"更新 bvid 算法 (#857)"},{"hash":"03eaaf52dc1d8a5bf1aeb847d5b42b681334551c","time":1696392355000,"email":"24969684+Kataick@users.noreply.github.com","author":"Kataick","message":"fix av2bv (#834)"},{"hash":"08e41c70e751a91097a753f2d9f935687d31c034","time":1695680686000,"email":"74277414+EvanHsieh0415@users.noreply.github.com","author":"Mango Jelly Pudding","message":"Update bvid_desc.md (#824)"},{"hash":"05ac3d5e2a9e28be3bf129ae8c78ffdbebaa161c","time":1684805901000,"email":"1440239038@qq.com","author":"SocialSisterYi","message":"添加文档【Wbi 接口签名】,修改目录结构"},{"hash":"dc5c527a1fe46d1d787d77d49e907e1ef7b03e67","time":1684179507000,"email":"stackinspector@126.com","author":"stackinspector","message":"添加Rust版本bvid算法示例"},{"hash":"f8a8f8a245c18a157c246246090f1e948b25fbab","time":1684176978000,"email":"stackinspector@126.com","author":"stackinspector","message":"添加Rust版本bvid算法"},{"hash":"06e8343031c77b39b97206542b9556d44ea64014","time":1684088758000,"email":"46991452+zine0@users.noreply.github.com","author":"zine_yu","message":"fix(docs/other/bvid_desc.md) (#663)"},{"hash":"f6760f4be38d5b592d396b211e48c666286524de","time":1677124138000,"email":"1440239038@qq.com","author":"SocialSisterYi","message":"🔨remove header index"},{"hash":"7d89ece2ac46425810647c4ac92acf5f3721cb68","time":1676998806000,"email":"1440239038@qq.com","author":"SocialSisterYi","message":"🚀调整项目结构"}]},"filePathRelative":"docs/misc/bvid_desc.md"}');export{E as comp,A as data};