fix Bilibili av/bv conversion failed when avid > 2^30

This commit is contained in:
A.C.Sukazyo Eyre 2024-02-13 14:04:49 +08:00
parent 961edd93f3
commit 9814b3ccab
Signed by: Eyre_S
GPG Key ID: C17CE40291207874
4 changed files with 28 additions and 15 deletions

View File

@ -5,7 +5,7 @@ MORNY_ARCHIVE_NAME = morny-coeur
MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono MORNY_CODE_STORE = https://github.com/Eyre-S/Coeur-Morny-Cono
MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s MORNY_COMMIT_PATH = https://github.com/Eyre-S/Coeur-Morny-Cono/commit/%s
VERSION = 1.3.0 VERSION = 1.3.1
USE_DELTA = false USE_DELTA = false
VERSION_DELTA = VERSION_DELTA =

View File

@ -30,12 +30,12 @@ object BiliTool {
private val V_CONV_XOR = 177451812L private val V_CONV_XOR = 177451812L
private val V_CONV_ADD = 8728348608L private val V_CONV_ADD = 8728348608L
private val BV_TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF" private val X_AV_MAX = Math.pow(2, 30).toLong
private val TABLE_INT = BV_TABLE.length private val X_AV_ALT = Int.MaxValue.toLong + 1
private val BV_TABLE_REVERSED =
val mapping = mutable.HashMap.empty[Char, Int] private val BB58_TABLE_REV: Map[Char, Int] = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF".toCharArray.zipWithIndex.toMap
for (i <- BV_TABLE.indices) mapping += (BV_TABLE(i) -> i) private val BB58_TABLE: Map[Int, Char] = BB58_TABLE_REV.map((k,v) => (v, k))
mapping.toMap private val BB58_TABLE_SIZE: Long = BB58_TABLE.size
private val BV_TEMPLATE = "1 4 1 7 " private val BV_TEMPLATE = "1 4 1 7 "
private val BV_TEMPLATE_FILTER = Array(9, 8, 1, 6, 2, 4) private val BV_TEMPLATE_FILTER = Array(9, 8, 1, 6, 2, 4)
@ -56,7 +56,7 @@ object BiliTool {
def this (bv: String, length: Int) = def this (bv: String, length: Int) =
this(bv, s"given length is $length") this(bv, s"given length is $length")
/** Error of illegal BV id, where the reason is the BV id contains non [[BV_TABLE base58 character]]. /** Error of illegal BV id, where the reason is the BV id contains non [[BB58_TABLE base58 character]].
* *
* @param bv the source of illegal BV id. * @param bv the source of illegal BV id.
* @param c the illegal character * @param c the illegal character
@ -79,7 +79,7 @@ object BiliTool {
* @see $AvBvSeeAlso * @see $AvBvSeeAlso
* *
* @param bv a BV id, which should be exactly 10 digits and all chars should be * @param bv a BV id, which should be exactly 10 digits and all chars should be
* a legal base58 char (which means can be found in [[BV_TABLE]]). * a legal base58 char (which means can be found in [[BB58_TABLE]]).
* otherwise, an [[IllegalFormatException]] will be thrown. * otherwise, an [[IllegalFormatException]] will be thrown.
* @return an AV id which will shows the save video of input __bv__ in $Bilibili * @return an AV id which will shows the save video of input __bv__ in $Bilibili
* @throws IllegalFormatException when the input __bv__ is not a legal 10 digits base58 * @throws IllegalFormatException when the input __bv__ is not a legal 10 digits base58
@ -91,11 +91,14 @@ object BiliTool {
if (bv.length != 10) throw IllegalFormatException(bv, bv.length) if (bv.length != 10) throw IllegalFormatException(bv, bv.length)
for (i <- BV_TEMPLATE_FILTER.indices) { for (i <- BV_TEMPLATE_FILTER.indices) {
val _get = BV_TEMPLATE_FILTER(i) val _get = BV_TEMPLATE_FILTER(i)
val tableToken = BV_TABLE_REVERSED get bv(_get) val tableToken = BB58_TABLE_REV get bv(_get)
if tableToken isEmpty then throw IllegalFormatException(bv, bv(_get), _get) if tableToken isEmpty then throw IllegalFormatException(bv, bv(_get), _get)
av = av + (tableToken.get * (TABLE_INT**i).toLong) av = av + (tableToken.get.toLong * (BB58_TABLE_SIZE**i).toLong)
} }
(av - V_CONV_ADD) ^ V_CONV_XOR av = (av - V_CONV_ADD) ^ V_CONV_XOR
if (av < 0)
av+ X_AV_ALT
else av
} }
/** Convert an AV video format to a BV video format for $Bilibili. /** Convert an AV video format to a BV video format for $Bilibili.
@ -107,11 +110,11 @@ object BiliTool {
* @return a BV id which will shows the save video of input __av__ in $Bilibili * @return a BV id which will shows the save video of input __av__ in $Bilibili
*/ */
def toBv (av: Long): String = { def toBv (av: Long): String = {
val _av = (av^V_CONV_XOR)+V_CONV_ADD val __av =if (av > X_AV_MAX) av - X_AV_ALT else av
val _av = (__av^V_CONV_XOR)+V_CONV_ADD
val bv = Array(BV_TEMPLATE:_*) val bv = Array(BV_TEMPLATE:_*)
for (i <- BV_TEMPLATE_FILTER.indices) { for (i <- BV_TEMPLATE_FILTER.indices) {
import Math.{floor, pow} bv(BV_TEMPLATE_FILTER(i)) = BB58_TABLE( (_av/(BB58_TABLE_SIZE**i) % BB58_TABLE_SIZE) toInt )
bv(BV_TEMPLATE_FILTER(i)) = BV_TABLE( (floor(_av/(TABLE_INT**i)) % TABLE_INT) toInt )
} }
String copyValueOf bv String copyValueOf bv
} }

View File

@ -16,6 +16,12 @@ object UseMath {
def ** (other: Int): Double = Math.pow(self, other) def ** (other: Int): Double = Math.pow(self, other)
} }
extension (self: Long) {
@targetName("pow")
def ** (other: Long): Long =
Math.pow(self, other).toLong
}
extension (base: Int) { extension (base: Int) {
def percentageOf (another: Int): Int = def percentageOf (another: Int): Int =
Math.round((another.toDouble/base)*100).toInt Math.round((another.toDouble/base)*100).toInt

View File

@ -13,6 +13,10 @@ class BiliToolTest extends MornyTests with TableDrivenPropertyChecks {
("1Q541167Qg", 455017605L), ("1Q541167Qg", 455017605L),
("1mK4y1C7Bz", 882584971L), ("1mK4y1C7Bz", 882584971L),
("1T24y197V2", 688730800L), ("1T24y197V2", 688730800L),
("1b2421A7FH", 1600345142L),
("1DB421k7zX", 1350018000L),
("19m411D7wx", 1900737470L),
("1LQ4y1A7im", 709042411L),
) )
forAll (examples) { (bv, av) => s"while using av$av/BV$bv :" - { forAll (examples) { (bv, av) => s"while using av$av/BV$bv :" - {