summaryrefslogtreecommitdiff
path: root/ATRI/plugins/utils/data_source.py
diff options
context:
space:
mode:
authorKyomotoi <[email protected]>2021-01-26 18:43:13 +0800
committerKyomotoi <[email protected]>2021-01-26 18:43:13 +0800
commit7640568a42493bc5a5e44bc82b1ecfa87e51c5f1 (patch)
tree60f29b756d58b085c95573515d3e4bd6f41426a8 /ATRI/plugins/utils/data_source.py
parentd0d31b2630697c97e848f00142f06b81f63b255a (diff)
downloadATRI-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.py239
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')