Skip to content

Commit

Permalink
重写BV=>av算法 #525
Browse files Browse the repository at this point in the history
  • Loading branch information
MotooriKashin committed Jan 30, 2024
1 parent 9e4dcca commit 9fff55e
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 71 deletions.
2 changes: 1 addition & 1 deletion chrome/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ window.addEventListener("beforeunload", () => {
});
});

documentPictureInPicture?.addEventListener('enter', e => {
self.documentPictureInPicture?.addEventListener('enter', e => {
if (documentPictureInPicture.window) {
const url = chrome.runtime.getURL('/player/video.css');
const link = document.createElement('link');
Expand Down
4 changes: 2 additions & 2 deletions src/core/comment.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { apiReply } from "../io/api-reply";
import { BV2avAll } from "../utils/abv";
import { AV } from "../utils/av";
import { addCss, addElement, loadScript } from "../utils/element";
import { urlObj } from "../utils/format/url";
import { jsonpHook } from "../utils/hook/node";
Expand Down Expand Up @@ -524,7 +524,7 @@ export class Comment {
}
}

return BV2avAll(str);
return AV.fromStr(str);
};
}
/** 评论图片 */
Expand Down
10 changes: 5 additions & 5 deletions src/core/url.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { abv, BV2avAll } from "../utils/abv";
import { AV } from "../utils/av";
import { URL } from "../utils/format/url";

/** 垃圾参数序列 */
Expand Down Expand Up @@ -62,11 +62,11 @@ class UrlCleaner {
const params = url.params;
// 旧版页面一般不支持bvid,转化为aid
if (params.bvid) {
params.aid = <string>abv(params.bvid);
params.aid = <string>AV.fromBV(<string>params.bvid);
}
// B站偶有发病出现名为aid实为bvid的情况
if (params.aid && !Number(params.aid)) {
params.aid = <string>abv(params.aid);
params.aid = <string>AV.fromBV(<string>params.aid);
}
// 通杀
paramsSet.forEach(d => { delete params[d]; });
Expand All @@ -78,8 +78,8 @@ class UrlCleaner {
}
}
});
url.base = BV2avAll(url.base);
url.hash && (url.hash = BV2avAll(url.hash));
url.base = AV.fromStr(url.base);
url.hash && (url.hash = AV.fromStr(url.hash));
return url.toJSON();
} else return str;
}
Expand Down
6 changes: 3 additions & 3 deletions src/io/api-webshow-locs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BV2avAll } from "../utils/abv";
import { AV } from "../utils/av";
import { objUrl } from "../utils/format/url";
import { jsonCheck, IApiData } from "./api";
import { URLS } from "./urls";
Expand All @@ -9,15 +9,15 @@ export async function apiWebshowLoc(id: number) {
id
}));
const text = await response.text();
return <IApiWebshowLocsResponse[]>jsonCheck(BV2avAll(text)).data;
return <IApiWebshowLocsResponse[]>jsonCheck(AV.fromStr(text)).data;
}
export async function apiWebshowLocs(data: IApiWebshowLocsData) {
const response = await fetch(objUrl(URLS.WEBSHOW_LOCS, {
pf: 0,
ids: data.ids.join(',')
}));
const text = await response.text();
return <IApiWebshowLocsResponse[][]>jsonCheck(BV2avAll(text)).data;
return <IApiWebshowLocsResponse[][]>jsonCheck(AV.fromStr(text)).data;
}

interface IApiWebshowLocsData extends IApiData {
Expand Down
4 changes: 2 additions & 2 deletions src/page/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { toast } from '../core/toast';
import html from '../html/read.html';
import { IStat } from "../io/api";
import { IUserInfo } from "../io/api-view-detail";
import { BV2avAll } from '../utils/abv';
import { debug } from "../utils/debug";
import { addCss, loadScript } from "../utils/element";
import { propertyHook } from "../utils/hook/method";
import { webpackHook } from '../utils/hook/webpack';
import { Page } from "./page";
import { AV } from '../utils/av';

interface ReadInfo {
act_id: number;
Expand Down Expand Up @@ -158,7 +158,7 @@ export class PageRead extends Page {
debug.error(e)
}
}
return BV2avAll(str);
return AV.fromStr(str);
}
protected tagContainer() {
this.readInfoStr += (this.readInfo.tags || []).reduce((o, d) => {
Expand Down
54 changes: 0 additions & 54 deletions src/utils/abv.ts

This file was deleted.

91 changes: 91 additions & 0 deletions src/utils/av.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/**
* @file av号工具
*/

export namespace AV {
const XOR_CODE = 23442827791579n;
const MASK_CODE = 2251799813685247n;

const MAX_AID = 1n << 51n;
const MIN_AID = 1n;

const BASE = 58n;
const BYTES = ['B', 'V', 1, '', '', '', '', '', '', '', '', ''];
const BV_LEN = BYTES.length;

const ALPHABET = [
'F', 'c', 'w', 'A', 'P', 'N', 'K', 'T', 'M', 'u', 'g', '3', 'G', 'V', '5', 'L',
'j', '7', 'E', 'J', 'n', 'H', 'p', 'W', 's', 'x', '4', 't', '', '8', 'h', 'a',
'Y', 'e', 'v', 'i', 'q', 'B', 'z', '6', 'r', 'k', 'C', 'y', '1', '2', 'm', 'U',
'S', 'D', 'Q', 'X', '9', 'R', 'd', 'o', 'Z', 'f'
];
const DIGIT_MAP = [0, 1, 2, 9, 7, 5, 6, 4, 8, 3, 10, 11];
const REG_EXP = new RegExp(`^[bB][vV]1[${ALPHABET.join('')}]{9}$`, 'g');
const REG_EXP_SHORT = new RegExp(`^1[${ALPHABET.join('')}]{9}$`, 'g');
const REG_EXP_STR = new RegExp(`[bB][vV]1[${ALPHABET.join('')}]{9}`, 'g');

/**
* aid => BV
*
* @example
* toBV(170001) // BV17x411w7KC
*/
export function toBV(avid: bigint | number) {
typeof avid === "bigint" || (avid = BigInt(avid));

if (avid < MIN_AID) {
throw new RangeError(`Av ${avid} is smaller than ${MIN_AID}`);
}
if (avid >= MAX_AID) {
throw new RangeError(`Av ${avid} is bigger than ${MAX_AID}`);
}

const bytes = Array.from(BYTES);

let bv_idx = BV_LEN - 1;
let tmp = (MAX_AID | avid) ^ XOR_CODE;
while (tmp !== 0n) {
let table_idx = tmp % BASE;
bytes[DIGIT_MAP[Number(bv_idx)]] = ALPHABET[Number(table_idx)];
tmp /= BASE;
bv_idx -= 1;
}

return bytes.join('');
}

/**
* BV => aid
*
* @example
* fromBV('BV17x411w7KC') // 170001
* fromBV('17x411w7KC') // 170001
*/
export function fromBV(bvid: string) {
if (REG_EXP_SHORT.test(bvid)) {
bvid = 'BV' + bvid;
}
if (!REG_EXP.test(bvid)) {
throw new TypeError(`${bvid} is illegal`);
}

let r = 0n;
for (let i = 3; i < BV_LEN; i++) {
r = r * BASE + BigInt(ALPHABET.indexOf(bvid[DIGIT_MAP[i]]));
}

return `${(r & MASK_CODE) ^ XOR_CODE}`;
}

/**
* 替换文本中所有BV号
*
* @param str 含有BV号的文本
* @returns 替换为av号的文本
* @example
* fromStr('***BV17x411w7KC***') // ***av170001***
*/
export function fromStr(str: string) {
return str.replace(REG_EXP_STR, (s: string) => "av" + fromBV(s));
}
}
8 changes: 4 additions & 4 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { apiBiliplusView } from "../io/api-biliplus-view";
import { apiPlayerPagelist } from "../io/api-player-pagelist";
import { apiView } from "../io/api-view";
import { apiXView } from "../io/api-x-view";
import { abv } from "./abv";
import { AV } from "./av";
import { debug } from "./debug";
import { objUrl, urlObj } from "./format/url";

Expand Down Expand Up @@ -55,9 +55,9 @@ export async function urlParam(url: string, redirect = true): Promise<UrlParam>
let pgc = false;
!aid && (aid = obj.avid);
!aid && (url.replace(/[aA][vV]\d+/, d => aid = d.substring(2)));
!aid && (url.replace(/[bB][vV]1[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}/, d => aid = <string>abv(d)));
!aid && obj.bvid && (aid = abv(obj.bvid));
aid && !Number(aid) && (aid = abv(aid));
!aid && (url.replace(/[bB][vV]1[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}/, d => aid = AV.fromBV(<string>d)));
!aid && obj.bvid && (aid = AV.fromBV(<string>obj.bvid));
aid && !Number(aid) && (aid = AV.fromBV(<string>aid));
p = p || 1;
!ssid && (ssid = obj.seasonId);
!ssid && (ssid = obj.season_id);
Expand Down

0 comments on commit 9fff55e

Please sign in to comment.