Nya_Twisuki 841b3e0d4e
petcat插件token解析部分 (#32)
* 新增了萌百插件(meowiki)

* 更新萌百搜索

* 删除萌百插件, 结束开发

* 新建MegaKits插件

* 修复

* 摩尔斯电码加密/解码

* 猫语转换/翻译

* 新增了养猫插件

* 数据加密解码处理完成

* 汉明码加密解码处理完成

* 进制转换

* 112位Bit数据解密

* 总解码完成

* 格式微调

* # 112位Bit数据编码

* 总编码完成

* 养猫插件上传

* 新的数据存储方式

* 进制转换

* bool byte转换

* Token解码

* Token编码

* 删除测试语句

* 测试句

* 修复二进制位错乱问题, 删去调试语句

* 添加了try-except异常处理语句

* 将异常返回值规整为变量

* 删去了调试语句

* 重命名pc_code.py为pc_token.py
2025-01-01 12:41:38 +08:00

194 lines
5.2 KiB
Python

# 由于无法直接存储数据, 使用一个字符串记录全部信息
# 这里作为引用进行编码/解码, 以及公用数据
"""猫对象属性存储编码Token
名字: 3位长度 + 8位ASCII字符 - 67b
年龄: 0 ~ 15 - 4b
种类: 8种 - 3b
生命值: 0 ~ 127 - 7b
饱食度: 0 ~ 127 - 7b
活力值: 0 ~ 127 - 7b
技能: 8种任选 - 8b
时间: 0 ~ 131017d > 2025-1-1 - 17b
总计120b有效数据
总计120b数据, 15字节, 每3字节(utf-8一个字符)转换为4个Base64字符
总计20个Base64字符的字符串
"""
"""定义变量
存储字符串: Token: str
对象数据: data: dict
名字: name: str
年龄: age: int
种类: type: int # 代表TYPE_LIST中的序号
生命值: health: int # 0 - 127, 显示时转换为100%
饱食度: saturation: int # 0 - 127, 显示时转换为100%
活力值: energy: int # 0 - 127, 显示时转换为100%
技能: skill: List[bool] # 8元素bool数组
时间: date: int # 到2025-1-1按日的时间戳
"""
import base64
from datetime import datetime
from typing import List
from nonebot.log import logger
# 公用列表
TYPE_LIST = ["猫1", "猫2", "猫3", "猫4", "猫5", "猫6", "猫7", "猫8"]
SKILL_LIST = ["s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8"]
# 私用列表
ERROR_DICT = {
"name": "ERROR!",
"age": 0,
"type": 0,
"health": 0,
"saturation": 0,
"energy": 0,
"skill": [False, False, False, False, False, False, False, False],
"date": 0,
}
ERROR_TOKEN = "yKpKSepEIAAAAAAAAAAA"
# bool数组/int数据转换
def bool_to_int(bool_array: List[bool]) -> int:
result = 0
for index, bit in enumerate(bool_array[::-1]):
if bit:
result |= 1 << index
return result
def int_to_bool(integer: int, length: int = 0) -> List[bool]:
bit_length = integer.bit_length()
bool_array = [False] * bit_length
for i in range(bit_length):
if integer & (1 << i):
bool_array[bit_length - 1 - i] = True
if len(bool_array) >= length:
return bool_array
else:
return [*([False] * (length - len(bool_array))), *bool_array]
# bool数组/byte数据转换
def bool_to_byte(bool_array: List[bool]) -> bytes:
byte_data = bytearray()
for i in range(0, len(bool_array), 8):
byte = 0
for j in range(8):
if i + j < len(bool_array) and bool_array[i + j]:
byte |= 1 << (7 - j)
byte_data.append(byte)
return bytes(byte_data)
def byte_to_bool(byte_data: bytes, length: int = 0) -> List[bool]:
bool_array = []
for byte in byte_data:
for bit in format(byte, "08b"):
bool_array.append(bit == "1")
if len(bool_array) >= length:
return bool_array
else:
return [*([False] * (length - len(bool_array))), *bool_array]
# 数据解码
def token_to_dict(token: str) -> dict:
data = {
"name": "Default0",
"age": 0,
"type": 0,
"health": 0,
"saturation": 0,
"energy": 0,
"skill": [False] * 8,
"date": 0,
}
# 转换token
try:
token_byte = base64.b64decode(token.encode())
code = byte_to_bool(token_byte)
except ValueError:
logger.error("token b64解码错误!")
return ERROR_DICT
# 拆分code
name_length = bool_to_int(code[0:3])
name_code = code[3:67]
age = bool_to_int(code[67:71])
type = bool_to_int(code[71:74])
health = bool_to_int(code[74:81])
saturation = bool_to_int(code[81:88])
energy = bool_to_int(code[88:95])
skill = code[95:103]
date = bool_to_int(code[103:120])
# 解析code
name = ""
try:
for i in range(name_length):
character_code = bool_to_byte(name_code[8 * i : 8 * i + 8])
name += character_code.decode("ASCII")
except UnicodeDecodeError:
logger.error("token ASCII解析错误!")
return ERROR_DICT
data["name"] = name
data["age"] = age
data["type"] = type
data["health"] = health
data["saturation"] = saturation
data["energy"] = energy
data["skill"] = skill
data["date"] = date
return data
# 数据编码
def dict_to_token(data: dict) -> str:
code = [False] * 120
# 拆分data
name_length = len(data["name"])
name = data["name"]
age = data["age"]
type = data["type"]
health = data["health"]
saturation = data["saturation"]
energy = data["energy"]
skill = data["skill"]
date = (datetime(2025, 1, 1) - datetime.now()).days
# 填入code
code[0:3] = int_to_bool(name_length, 3)
name_code = [False] * 64
try:
for i in range(name_length):
character_code = byte_to_bool(name[i].encode("ASCII"), 8)
name_code[8 * i : 8 * i + 8] = character_code
except UnicodeEncodeError:
# "name": "ERROR!"
logger.error("name内含有非法字符!")
return ERROR_TOKEN
code[3:67] = name_code
code[67:71] = int_to_bool(age, 4)
code[71:74] = int_to_bool(type, 3)
code[74:81] = int_to_bool(health, 7)
code[81:88] = int_to_bool(saturation, 7)
code[88:95] = int_to_bool(energy, 7)
code[95:103] = skill
code[103:120] = int_to_bool(date, 17)
# 转换token
token_byte = bool_to_byte(code)
token = base64.b64encode(token_byte).decode()
return token