From 11d42851ae07fd95f8af37a354c672f07f999ad2 Mon Sep 17 00:00:00 2001 From: cctyl <34262992+cctyl@users.noreply.github.com> Date: Mon, 20 May 2024 23:42:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20bv<-->av=20=E5=A2=9E=E5=8A=A0java?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20(#1021)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/misc/bvid_desc.md | 81 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/docs/misc/bvid_desc.md b/docs/misc/bvid_desc.md index 86c80c6e7b..f480b1c6b4 100644 --- a/docs/misc/bvid_desc.md +++ b/docs/misc/bvid_desc.md @@ -248,6 +248,87 @@ 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(int 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 -= 1; + } + swap(bytes, 3, 9); + swap(bytes, 4, 7); + StringBuilder sb = new StringBuilder(bytes.length); + for (Character ch : bytes) { + sb.append(ch); + } + return sb.toString(); + } + + public static int 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.intValue(); + } + + + 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; + } +} + +``` + + ## 老版算法存档 **以下算法已失效**,编解码函数值域有限,不推荐使用,在此仅作为存档