File size: 5,578 Bytes
0aee47a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
"""
bilibili_api.utils.utils
通用工具库。
"""
import json
import os
import random
from typing import List, TypeVar
from ..exceptions import StatementException
def get_api(field: str, *args) -> dict:
"""
获取 API。
Args:
field (str): API 所属分类,即 data/api 下的文件名(不含后缀名)
Returns:
dict, 该 API 的内容。
"""
path = os.path.abspath(
os.path.join(
os.path.dirname(__file__), "..", "data", "api", f"{field.lower()}.json"
)
)
if os.path.exists(path):
with open(path, encoding="utf8") as f:
data = json.load(f)
for arg in args:
data = data[arg]
return data
else:
return {}
def crack_uid(crc32: str):
"""
弹幕中的 CRC32 ID 转换成用户 UID。
警告,破解后的 UID 不一定准确,有存在误差,仅供参考。
代码翻译自:https://github.com/esterTion/BiliBili_crc2mid。
Args:
crc32 (str): crc32 计算摘要后的 UID。
Returns:
int, 真实用户 UID,不一定准确。
"""
__CRCPOLYNOMIAL = 0xEDB88320
__crctable = [None] * 256
__index = [None] * 4
def __create_table():
for i in range(256):
crcreg = i
for j in range(8):
if (crcreg & 1) != 0:
crcreg = __CRCPOLYNOMIAL ^ (crcreg >> 1)
else:
crcreg >>= 1
__crctable[i] = crcreg
__create_table()
def __crc32(input_):
if type(input_) != str:
input_ = str(input_)
crcstart = 0xFFFFFFFF
len_ = len(input_)
for i in range(len_):
index = (crcstart ^ ord(input_[i])) & 0xFF
crcstart = (crcstart >> 8) ^ __crctable[index]
return crcstart
def __crc32lastindex(input_):
if type(input_) != str:
input_ = str(input_)
crcstart = 0xFFFFFFFF
len_ = len(input_)
index = None
for i in range(len_):
index = (crcstart ^ ord(input_[i])) & 0xFF
crcstart = (crcstart >> 8) ^ __crctable[index]
return index
def __getcrcindex(t):
for i in range(256):
if __crctable[i] >> 24 == t:
return i
return -1
def __deepCheck(i, index):
tc = 0x00
str_ = ""
hash_ = __crc32(i)
tc = hash_ & 0xFF ^ index[2]
if not (57 >= tc >= 48):
return [0]
str_ += str(tc - 48)
hash_ = __crctable[index[2]] ^ (hash_ >> 8)
tc = hash_ & 0xFF ^ index[1]
if not (57 >= tc >= 48):
return [0]
str_ += str(tc - 48)
hash_ = __crctable[index[1]] ^ (hash_ >> 8)
tc = hash_ & 0xFF ^ index[0]
if not (57 >= tc >= 48):
return [0]
str_ += str(tc - 48)
hash_ = __crctable[index[0]] ^ (hash_ >> 8)
return [1, str_]
ht = int(crc32, 16) ^ 0xFFFFFFFF
i = 3
while i >= 0:
__index[3 - i] = __getcrcindex(ht >> (i * 8))
# pylint: disable=invalid-sequence-index
snum = __crctable[__index[3 - i]]
ht ^= snum >> ((3 - i) * 8)
i -= 1
for i in range(10000000):
lastindex = __crc32lastindex(i)
if lastindex == __index[3]:
deepCheckData = __deepCheck(i, __index)
if deepCheckData[0]:
break
if i == 10000000:
return -1
return str(i) + deepCheckData[1]
def join(seperator: str, array: list):
"""
用指定字符连接数组
Args:
seperator (str) : 分隔字符
array (list): 数组
Returns:
str: 连接结果
"""
return seperator.join(map(lambda x: str(x), array))
ChunkT = TypeVar("ChunkT", List, List)
def chunk(arr: ChunkT, size: int) -> List[ChunkT]:
if size <= 0:
raise Exception('Parameter "size" must greater than 0')
result = []
temp = []
for i in range(len(arr)):
temp.append(arr[i])
if i % size == size - 1:
result.append(temp)
temp = []
if temp:
result.append(temp)
return result
def get_deviceid(separator: str = "-", is_lowercase: bool = False) -> str:
"""
获取随机 deviceid (dev_id)
Args:
separator (str) : 分隔符 默认为 "-"
is_lowercase (bool) : 是否以小写形式 默认为False
参考: https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/message/private_msg.md#发送私信web端
Returns:
str: device_id
"""
template = ["xxxxxxxx", "xxxx", "4xxx", "yxxx", "xxxxxxxxxxxx"]
dev_id_group = []
for i in range(len(template)):
s = ""
group = template[i]
for k in group:
rand: int = int(16 * random.random())
if k in "xy":
if k == "x":
s += hex(rand)[2:]
else:
s += hex(3 & rand | 8)[2:]
else:
s += "4"
dev_id_group.append(s)
res = join(separator, dev_id_group)
return res if is_lowercase else res.upper()
def raise_for_statement(statement: bool, msg: str="未满足条件") -> None:
if not statement:
raise StatementException(msg=msg)
|