diff options
author | Kyomotoi <[email protected]> | 2021-01-26 18:43:13 +0800 |
---|---|---|
committer | Kyomotoi <[email protected]> | 2021-01-26 18:43:13 +0800 |
commit | 7640568a42493bc5a5e44bc82b1ecfa87e51c5f1 (patch) | |
tree | 60f29b756d58b085c95573515d3e4bd6f41426a8 /ATRI/plugins/utils/data_source.py | |
parent | d0d31b2630697c97e848f00142f06b81f63b255a (diff) | |
download | ATRI-7640568a42493bc5a5e44bc82b1ecfa87e51c5f1.tar.gz ATRI-7640568a42493bc5a5e44bc82b1ecfa87e51c5f1.tar.bz2 ATRI-7640568a42493bc5a5e44bc82b1ecfa87e51c5f1.zip |
[Update]
Diffstat (limited to 'ATRI/plugins/utils/data_source.py')
-rw-r--r-- | ATRI/plugins/utils/data_source.py | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/ATRI/plugins/utils/data_source.py b/ATRI/plugins/utils/data_source.py new file mode 100644 index 0000000..4d7ddb6 --- /dev/null +++ b/ATRI/plugins/utils/data_source.py @@ -0,0 +1,239 @@ +import re +import os +import json +import random +from math import floor +from pathlib import Path +from zipfile import PyZipFile +from typing import Tuple, Union +from random import choice, randint +from typing import Dict, List + +from ATRI.config import UTILS_CONFIG + + +class Function: + @staticmethod + def roll_dice(par: str) -> str: + result = 0 + proc = '' + proc_list = [] + p = par.split('+') + + for i in p: + args = re.findall(r"(\d{0,10})(?:(d)(\d{1,10}))", i) + args = list(args[0]) + if not args[0]: + args[0] = 1 + if int(args[0]) >= 5000 or int(args[2]) >= 5000: + return choice(UTILS_CONFIG['utils']['roll']['tooBig']['repo']) + for a in range(1, int(args[0]) + 1): + rd = randint(1, int(args[2])) + result = result + rd + if len(proc_list) <= 10: + proc_list.append(rd) + + if len(proc_list) <= 10: + proc += '+'.join(map(str, proc_list)) + elif len(proc_list) >= 10: + proc += choice(UTILS_CONFIG['utils']['roll']['tooLong']['repo']) + else: + proc += str(result) + + msg = f'{par}=({proc})={result}' + print(msg) + return msg + + class Generate: + ''' + (*彩蛋*) + 由于此功能触及法律故不用作上线功能,写于此地只为学习 + 请勿用作网上购物、交易和注册 + 随机身份证根据国家标准(GB11643-1999)生成 + 并不存在所谓: + - 生成在逃犯号码 + ''' + @classmethod + def __init__(cls) -> None: + cls.DATA_PATH = Path('.') / 'ATRI' / 'plugins' / 'utils' / 'main.bin' + + @classmethod + def info_id(cls) -> Tuple[Dict[str, List[str]], Dict[str, str]]: + with PyZipFile(os.path.abspath(cls.DATA_PATH), 'r') as zipFile: + with zipFile.open('name.json', 'r') as f: + name = json.loads(f.read().decode()) + with zipFile.open('area.json', 'r') as f: + area = json.loads(f.read().decode()) + return name, area + + @staticmethod + def number_id(area: int, gender: int, birth: int) -> str: + ''' + 校验码计算公式: (12-∑(Ai×Wi)(mod 11))mod 11 + 验证公式: 请查阅(ISO 7064:1983.MOD 11-2) + ''' + def check_sum(full_code: str): + assert len(full_code) == 17 + check_sum = sum([((1 << (17 - i)) % 11) * int(full_code[i]) + for i in range(0, 17)]) + check_digit = (12 - (check_sum % 11)) % 11 + if check_digit < 10: + return check_digit + else: + return 'X' + + order_code = str(random.randint(10, 99)) + gender_code = str(random.randrange(gender, 10, step=2)) + full_code = str(area) + str(birth) + str(order_code) + str(gender_code) + full_code += str(check_sum(full_code)) + return full_code + + class RCNB: + @classmethod + def __init__(cls) -> None: + cls.cr = 'rRŔŕŖŗŘřƦȐȑȒȓɌɍ' + cls.cc = 'cCĆćĈĉĊċČčƇƈÇȻȼ' + cls.cn = 'nNŃńŅņŇňƝƞÑǸǹȠȵ' + cls.cb = 'bBƀƁƃƄƅßÞþ' + + cls.sr = len(cls.cr) + cls.sc = len(cls.cc) + cls.sn = len(cls.cn) + cls.sb = len(cls.cb) + cls.src = cls.sr * cls.sc + cls.snb = cls.sn * cls.sb + cls.scnb = cls.sc * cls.snb + + @staticmethod + def _div(a: int, b: int) -> int: + return floor(a / b) + + @classmethod + def _encode_byte(cls, i) -> Union[str, None]: + if i > 0xFF: + raise ValueError('ERROR! rc/nb overflow') + + if i > 0x7F: + i = i & 0x7F + return cls.cn[i // cls.sb] + cls.cb[i % cls.sb] + # return f'{cls.cn[i // cls.sb]}{cls.cb[i % cls.sb]}' + # return cls.cn[cls._div(i, cls.sb) + int(cls.cb[i % cls.sb])] + + return cls.cr[i // cls.sc] + cls.cc[i % cls.sc] + # return cls.cr[cls._div(i, cls.sc) + int(cls.cc[i % cls.sc])] + + @classmethod + def _encode_short(cls, i) -> str: + if i > 0xFFFF: + raise ValueError('ERROR! rcnb overflow') + + reverse = False + if i > 0x7FFF: + reverse = True + i = i & 0x7FFF + + char = [ + cls._div(i, cls.scnb), + cls._div(i % cls.scnb, cls.snb), + cls._div(i % cls.snb, cls.sb), i % cls.sb + ] + char = [ + cls.cr[char[0]], cls.cc[char[1]], cls.cn[char[2]], + cls.cb[char[3]] + ] + + if reverse: + return char[2] + char[3] + char[0] + char[1] + + return ''.join(char) + + @classmethod + def _decodeByte(cls, c) -> int: + nb = False + idx = [cls.cr.index(c[0]), cls.cc.index(c[1])] + if idx[0] < 0 or idx[1] < 0: + idx = [cls.cn.index(c[0]), cls.cb.index(c[1])] + nb = True + raise ValueError('ERROR! rc/nb overflow') + + result = idx[0] * cls.sb + idx[1] if nb else idx[0] * cls.sc + idx[1] + if result > 0x7F: + raise ValueError('ERROR! rc/nb overflow') + + return result | 0x80 if nb else 0 + + @classmethod + def _decodeShort(cls, c) -> int: + reverse = c[0] not in cls.cr + if not reverse: + idx = [ + cls.cr.index(c[0]), + cls.cc.index(c[1]), + cls.cn.index(c[2]), + cls.cb.index(c[3]) + ] + else: + idx = [ + cls.cr.index(c[2]), + cls.cc.index(c[3]), + cls.cn.index(c[0]), + cls.cb.index(c[1]) + ] + + if idx[0] < 0 or idx[1] < 0 or idx[2] < 0 or idx[3] < 0: + raise ValueError('ERROR! not rcnb') + + result = (idx[0] * cls.scnb + + idx[1] * cls.snb + + idx[2] * cls.sb + idx[3]) + if result > 0x7FFF: + raise ValueError('ERROR! rcnb overflow') + + result |= 0x8000 if reverse else 0 + return result + + @classmethod + def _encodeBytes(cls, b) -> str: + result = [] + for i in range(0, (len(b) >> 1)): + result.append(cls._encode_short((b[i * 2] << 8 | b[i * 2 + 1]))) + + if len(b) & 1 == 1: + result.append(cls._encode_byte(b[-1])) + + return ''.join(result) + + @classmethod + def encode(cls, s: str, encoding: str = 'utf-8'): + if not isinstance(s, str): + raise ValueError('Please enter str instead of other') + + return cls._encodeBytes(s.encode(encoding)) + + @classmethod + def _decodeBytes(cls, s: str): + if not isinstance(s, str): + raise ValueError('Please enter str instead of other') + + if len(s) & 1: + raise ValueError('ERROR length') + + result = [] + for i in range(0, (len(s) >> 2)): + result.append(bytes([cls._decodeShort(s[i * 4:i * 4 + 4]) >> 8])) + result.append(bytes([cls._decodeShort(s[i * 4:i * 4 + 4]) & 0xFF])) + + if (len(s) & 2) == 2: + result.append(bytes([cls._decodeByte(s[-2:])])) + + return b''.join(result) + + @classmethod + def decode(cls, s: str, encoding: str = 'utf-8') -> str: + if not isinstance(s, str): + raise ValueError('Please enter str instead of other') + + try: + return cls._decodeBytes(s).decode(encoding) + except UnicodeDecodeError: + raise ValueError('Decoding failed') |