Repository: gera2ld/qqlib Branch: master Commit: 1c6417ea4d60 Files: 14 Total size: 49.5 KB Directory structure: gitextract_m9887sgl/ ├── .editorconfig ├── .gitignore ├── README.md ├── qqlib/ │ ├── __init__.py │ ├── __main__.py │ ├── hieroglyphy/ │ │ ├── __init__.py │ │ └── data.py │ ├── qzone.py │ └── tea.py ├── requirements.txt ├── setup.py └── tests/ ├── __init__.py ├── test_hieroglyphy.py └── test_tea.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [*.md] trim_trailing_whitespace = false [*.py] indent_size = 4 ================================================ FILE: .gitignore ================================================ __pycache__/ *.pyc python*/ *.egg-info/ /build /dist ================================================ FILE: README.md ================================================ qqlib === [![PyPI](https://img.shields.io/pypi/v/qqlib.svg)]() Python版QQ登录库,兼容Python2.x和Python3.x。 安装 --- ``` sh $ pip install qqlib # or $ pip install git+https://github.com/gera2ld/qqlib.git ``` 快速开始 --- ``` sh $ python -m qqlib ``` 高级用法 --- ``` python def login(qq): # 不考虑验证码的情况,直接登录 qq.login() import qqlib qq = qqlib.QQ(12345678, 'password') login(qq) print('Hi, %s' % qq.nick) ``` 登录时有可能出现需要验证码的情况,可以捕获到`qqlib.NeedVerifyCode`错误。这时`qq.need_verify`为`True`,需要获取验证码图片(`qq.verifier.fetch_image()`)进行处理,验证(`qq.verifier.verify(code)`)之后再继续登录。下面是支持输入验证码的`login`方法: ``` python def login(qq): # 自动重试登录 while True: try: if qq.need_verify: open('verify.jpg', 'wb').write(qq.verifier.fetch_image()) print('验证码已保存到verify.jpg') # 输入验证码 vcode = input('请输入验证码:') qq.verifier.verify(vcode) qq.login() break except qqlib.NeedVerifyCode as exc: if exc.message: print('Error:', exc.message) ``` QZone: ``` python from qqlib import qzone qq = qzone.QZone(12345678, 'password') # 登录流程同上 login(qq) qq.feed('发一条说说') ``` 测试 --- ``` sh # Python 2 $ python -m unittest discover # Python 3 $ python3 -m unittest ``` ================================================ FILE: qqlib/__init__.py ================================================ ''' QQ Login module Licensed to MIT ''' import hashlib, re, binascii, base64 import rsa, requests from . import tea __all__ = ['QQ', 'LogInError', 'NeedVerifyCode'] class LogInError(Exception): pass class NeedVerifyCode(Exception): def __init__(self, verifier, message=None): Exception.__init__(self) self.verifier = verifier self.message = message class Verifier: url_check = 'http://check.ptlogin2.qq.com/check' url_gettype = 'http://captcha.qq.com/cap_union_new_gettype' url_getsig = 'http://captcha.qq.com/cap_union_new_getsig' url_getimage = 'http://captcha.qq.com/cap_union_new_getcapbysig' url_verify = 'http://captcha.qq.com/cap_union_new_verify' def __init__(self, parent): self.parent = parent self.sess = None self.need_verify = False def check(self): parent = self.parent login_sig = parent.session.cookies['pt_login_sig'] g = parent.fetch(self.url_check, params={ 'pt_tea': 2, 'uin': parent.user, 'appid': parent.appid, 'js_ver': parent.js_ver, 'js_type': 1, 'u1': parent.url_success, 'login_sig': login_sig, }).text v = re.findall('\'(.*?)\'', g) self.pt_vcode_v1, self.cap_cd, self.uin, self.ptvfsession = v[:4] if self.pt_vcode_v1 == '1': self.throw() else: self.vcode = self.cap_cd def get_type(self): parent = self.parent g = parent.fetch(self.url_gettype, params={ 'aid': parent.appid, 'protocol': 'http', 'clienttype': 2, 'apptype': 2, 'curenv': 'inner', 'uid': parent.user, 'cap_cd': self.cap_cd, 'callback': '_qqlib_', }).text m = re.search('"sess":"(.*?)"', g) self.sess = m.group(1) def fetch_image(self): parent = self.parent if self.sess is None: self.get_type() g = parent.fetch(self.url_getsig, params={ 'aid': parent.appid, 'protocol': 'http', 'clienttype': 2, 'apptype': 2, 'curenv': 'inner', 'sess': self.sess, 'uid': parent.user, 'cap_cd': self.cap_cd, }).json() self.vsig = g['vsig'] r = parent.fetch(self.url_getimage, params={ 'aid': parent.appid, 'protocol': 'http', 'clienttype': 2, 'apptype': 2, 'curenv': 'inner', 'sess': self.sess, 'uid': parent.user, 'cap_cd': self.cap_cd, 'vsig': self.vsig, 'showtype': 'embed', 'ischartype': 1, }) return r.content def verify(self, vcode): parent = self.parent r = parent.fetch(self.url_verify, data={ 'aid': parent.appid, 'protocol': 'http', 'clientype': 2, 'apptype': 2, 'curenv': 'inner', 'sess': self.sess, 'uid': parent.user, 'cap_cd': self.cap_cd, 'vsig': self.vsig, 'ans': vcode, }) r.encoding='utf-8' g = r.json() if g['errorCode'] != '0': self.throw(g['errMessage']) self.vcode = g['randstr'] self.ptvfsession = g['ticket'] self.need_verify = False def throw(self, message=None): self.need_verify = True raise NeedVerifyCode(self, message) class QQ: appid = 549000912 action = '4-22-1450611437613' url_success = 'http://qzs.qq.com/qzone/v5/loginsucc.html?para=izone' js_ver = 10171 def __init__(self, user, pwd): self.user = user self.pwd = pwd self.nick = None self.verifier = None self.session = requests.Session() self.xlogin() def fetch(self, url, data=None, **kw): if data is None: func = self.session.get else: kw['data'] = data func = self.session.post return func(url, **kw) url_xlogin = 'http://xui.ptlogin2.qq.com/cgi-bin/xlogin' def xlogin(self): ''' Get a log-in signature in cookies. ''' self.fetch(self.url_xlogin, params={ 'proxy_url': 'http://qzs.qq.com/qzone/v6/portal/proxy.html', 'daid': 5, 'no_verifyimg': 1, 'appid': self.appid, 's_url': self.url_success, }) url_login = 'http://ptlogin2.qq.com/login' def login(self, force=False): login_sig = self.session.cookies['pt_login_sig'] if force: self.verifier = None if self.verifier is None: verifier = self.verifier = Verifier(self) verifier.check() else: verifier = self.verifier ptvfsession = verifier.ptvfsession or self.session.cookies.get('ptvfsession', '') g = self.fetch(self.url_login, params={ 'u': self.user, 'verifycode': verifier.vcode, 'pt_vcode_v1': verifier.pt_vcode_v1, 'pt_verifysession_v1': ptvfsession, 'p': self.pwdencode(verifier.vcode, verifier.uin, self.pwd), 'pt_randsalt': 0, 'u1': self.url_success, 'ptredirect': 0, 'h': 1, 't': 1, 'g': 1, 'from_ui': 1, 'ptlang': 2052, 'action': self.action, 'js_ver': self.js_ver, 'js_type': 1, 'aid': self.appid, 'daid': 5, 'login_sig': login_sig, }).text r = re.findall('\'(.*?)\'', g) if r[0] == '4': verifier.throw(r[4]) if r[0] != '0': raise LogInError(r[4]) self.nick = r[5] self.fetch(r[2]) self.verifier = None @property def need_verify(self): return self.verifier and self.verifier.need_verify def fromhex(self, s): # Python 3: bytes.fromhex return bytes(bytearray.fromhex(s)) pubKey = rsa.PublicKey(int( 'F20CE00BAE5361F8FA3AE9CEFA495362' 'FF7DA1BA628F64A347F0A8C012BF0B25' '4A30CD92ABFFE7A6EE0DC424CB6166F8' '819EFA5BCCB20EDFB4AD02E412CCF579' 'B1CA711D55B8B0B3AEB60153D5E0693A' '2A86F3167D7847A0CB8B00004716A909' '5D9BADC977CBB804DBDCBA6029A97108' '69A453F27DFDDF83C016D928B3CBF4C7', 16 ), 3) def pwdencode(self, vcode, uin, pwd): ''' Encode password with tea. ''' # uin is the bytes of QQ number stored in unsigned long (8 bytes) salt = uin.replace(r'\x', '') h1 = hashlib.md5(pwd.encode()).digest() s2 = hashlib.md5(h1 + self.fromhex(salt)).hexdigest().upper() rsaH1 = binascii.b2a_hex(rsa.encrypt(h1, self.pubKey)).decode() rsaH1Len = hex(len(rsaH1) // 2)[2:] hexVcode = binascii.b2a_hex(vcode.upper().encode()).decode() vcodeLen = hex(len(hexVcode) // 2)[2:] l = len(vcodeLen) if l < 4: vcodeLen = '0' * (4 - l) + vcodeLen l = len(rsaH1Len) if l < 4: rsaH1Len = '0' * (4 - l) + rsaH1Len pwd1 = rsaH1Len + rsaH1 + salt + vcodeLen + hexVcode saltPwd = base64.b64encode( tea.encrypt(self.fromhex(pwd1), self.fromhex(s2)) ).decode().replace('/', '-').replace('+', '*').replace('=', '_') return saltPwd ================================================ FILE: qqlib/__main__.py ================================================ import getpass, sys, tempfile, os from . import QQ, NeedVerifyCode quser = input('QQ: ') qpwd = getpass.getpass('Password: ') qq = QQ(quser, qpwd) while True: try: if qq.need_verify: fd, path = tempfile.mkstemp(suffix='.jpg') os.write(fd, qq.verifier.fetch_image()) os.close(fd) print('Verify code is saved to:', path) vcode = input('Input verify code: ') os.remove(path) qq.verifier.verify(vcode) qq.login() break except NeedVerifyCode: exc = sys.exc_info()[1] if exc.message: print('Error:', exc.message) exc = None print('Hi, %s' % qq.nick) ================================================ FILE: qqlib/hieroglyphy/__init__.py ================================================ ''' Decode hieroglyphy with Python @author Gerald Reference: - http://patriciopalladino.com/files/hieroglyphy/ - https://github.com/alcuadrado/hieroglyphy QZone uses hieroglyphy but changed `f` ''' # Generate mappings with JavaScript: # Run it at http://patriciopalladino.com/files/hieroglyphy/ # > 'mappings = ' + JSON.stringify('0123456789abcdeghijklmnopqrstuvwxyz'.split('').reduce((res, c) => {res[c] = hieroglyphy.hieroglyphyString(c).replace(/\+\[\]$/, ''); return res;}, {f:'(![]+[])[+[]]'}), null, 4) # Store it to ./data.py from .data import mappings class CannotDecodeError(Exception): pass def decode(text): remained = text results = [] while remained: for key, val in mappings.items(): if remained == val or remained.startswith(val + '+'): results.append(key) remained = remained[len(val) + 1:] break else: print(''.join(results), remained) raise CannotDecodeError(text) return ''.join(results) ================================================ FILE: qqlib/hieroglyphy/data.py ================================================ mappings = {"0":"(+[]+[])","1":"(+!![]+[])","2":"(!+[]+!![]+[])","3":"(!+[]+!![]+!![]+[])","4":"(!+[]+!![]+!![]+!![]+[])","5":"(!+[]+!![]+!![]+!![]+!![]+[])","6":"(!+[]+!![]+!![]+!![]+!![]+!![]+[])","7":"(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])","8":"(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])","9":"(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])","f":"(![]+[])[+[]]","a":"(+{}+[])[+!![]]","b":"([]+{})[!+[]+!![]]","c":"([]+{})[!+[]+!![]+!![]+!![]+!![]]","d":"([][[]]+[])[!+[]+!![]]","e":"([][[]]+[])[!+[]+!![]+!![]]","g":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[]))","h":"([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[+[]]","i":"([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]","j":"([]+{})[!+[]+!![]+!![]]","k":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]])","l":"(![]+[])[!+[]+!![]]","m":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+([][[]]+[])[!+[]+!![]])","n":"([][[]]+[])[+!![]]","o":"([]+{})[+!![]]","p":"([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]","q":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+!![]+[]))","r":"(!![]+[])[+!![]]","s":"(![]+[])[!+[]+!![]+!![]]","t":"(!![]+[])[+[]]","u":"([][[]]+[])[+[]]","v":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[]))","w":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[]))","x":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[]))","y":"(+(+!![]+([][[]]+[])[!+[]+!![]+!![]]+(+!![]+[])+(+[]+[])+(+[]+[])+(+[]+[]))+[])[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]","z":"[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[+[]]+([][[]]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()([][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[!+[]+!![]+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+([]+[][(![]+[])[!+[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[])[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[]]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]]+([][[]]+[])[+!![]])())[!+[]+!![]+!![]]+([][[]]+[])[!+[]+!![]+!![]])()(([]+{})[+[]])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+{}+[])[+!![]])"} ================================================ FILE: qqlib/qzone.py ================================================ ''' QZone module ''' from . import QQ from . import hieroglyphy class QZone(QQ): url_success = 'http://qzs.qq.com/qzone/v5/loginsucc.html?para=izone' url_feed = 'http://taotao.qzone.qq.com/cgi-bin/emotion_cgi_publish_v6' url_home = 'https://user.qzone.qq.com/' def g_tk(self): h = 5381 cookies = self.session.cookies s = cookies.get('p_skey') or cookies.get('skey') or '' for c in s: h += (h << 5) + ord(c) return h & 0x7fffffff def _qzonetoken(self, res, start_str, end_str=';'): i = res.find(start_str) j = res.find(';', i) assert i > 0, 'qzonetoken not found!' raw = res[i + len(start_str) : j] return hieroglyphy.decode(raw) def qzonetoken(self): self.fetch(self.url_success) res = self.fetch(self.url_home + str(self.user), headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36', }).text return self._qzonetoken(res, 'window.g_qzonetoken = (function(){ try{return ') def _feed(self, data): return self.fetch(self.url_feed, params={ 'g_tk': self.g_tk(), 'qzonetoken': self.qzonetoken(), }, data = { 'syn_tweet_verson' : 1, 'paramstr' : 1, 'pic_template' : '', 'richtype' : '', 'richval' : '', 'special_url' : '', 'subrichtype' : '', 'who' : 1, 'con' : data, 'feedversion' : 1, 'ver' : 1, 'ugc_right' : 1, 'to_tweet' : 0, 'to_sign' : 0, 'hostuin' : self.user, 'code_version' : 1, 'format' : 'fs' }) def feed(self, data): res = self._feed(data) res.raise_for_status() class MQZone(QZone): url_success = 'https://h5.qzone.qq.com/mqzone/index' url_feed = 'https://mobile.qzone.qq.com/mood/publish_mood' def qzonetoken(self): res = self.fetch(self.url_success).text return self._qzonetoken(res, 'window.shine0callback = (function(){ try{return ') def _feed(self, data): return self.fetch(self.url_feed, params={ 'g_tk': self.g_tk(), 'qzonetoken': self.qzonetoken(), }, data = { 'opr_type': 'publish_shuoshuo', 'res_uin': self.user, 'content': data, 'richval': '', 'lat': 0, 'lon': 0, 'lbsid': '', 'issyncweibo': 0, 'format': 'json', }) ================================================ FILE: qqlib/tea.py ================================================ ''' QQ Crypt module Licensed to MIT ''' import struct, ctypes import os __all__ = ['encrypt', 'decrypt'] def xor8B(a, b): ''' XOR operation between two 8B bytes. ''' length = 8 arr_a = bytearray(a[:length]) arr_b = bytearray(b[:length]) for i in range(length): arr_a[i] ^= arr_b[i] return bytes(arr_a) if isinstance(a, bytes) else arr_a def encipher(v, k): ''' TEA coder encrypt 64 bits value, by 128 bits key, QQ uses 16 round TEA. http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html . ''' n=16 #qq use 16 delta = 0x9e3779b9 k = struct.unpack('!LLLL', k[0:16]) y, z = map(ctypes.c_uint32, struct.unpack('!LL', v[0:8])) s = ctypes.c_uint32(0) for i in range(n): s.value += delta y.value += (z.value << 4) + k[0] ^ z.value+ s.value ^ (z.value >> 5) + k[1] z.value += (y.value << 4) + k[2] ^ y.value+ s.value ^ (y.value >> 5) + k[3] r = struct.pack('!LL', y.value, z.value) return r def encrypt(v, k): """ Encrypt function for QQ. v is the message to encrypt, k is the key fill char is randomized (which is 0xAD in old version) the length of the final data is filln + 8 + len(v) The message is encrypted 8 bytes at at time, the result is: r = encipher( v ^ tr, key) ^ to (*) `encipher` is the QQ's TEA function. v is 8 bytes data to be encrypted. tr is the result in preceding round. to is the data coded in perceding round (v_pre ^ r_pre_pre) For the first 8 bytes 'tr' and 'to' is filled by zero. """ vl = len(v) #filln = (8 - (vl + 2)) % 8 filln = (6 - vl) % 8 v_arr = ( bytes(bytearray([filln | 0xf8])), os.urandom(filln + 2), # random char * (filln + 2) v, b'\0' * 7, ) v = b''.join(v_arr) tr = to = b'\0' * 8 r = [] for i in range(0, len(v), 8): o = xor8B(v[i:i+8], tr) tr = xor8B(encipher(o, k), to) to = o r.append(tr) r = b''.join(r) return r def decrypt(v, k): """ Decrypt function for QQ. according to (*) we can get: x = decipher(v[i:i+8] ^ prePlain, key) ^ preCyrpt prePlain is the previously encrypted 8 bytes: per 8 byte from v XOR previous preCyrpt preCrypt is previous 8 bytes of encrypted data. After decrypting, we must truncate the padding bytes. The number of padding bytes in the front of message is pos + 1. pos is the first byte of deCrypted: r[0] & 0x07 + 2 The number of padding bytes in the end is 7 (b'\0' * 7). The returned value is r[pos+1:-7]. >>> from binascii import a2b_hex, b2a_hex >>> r = encrypt('', b2a_hex('b537a06cf3bcb33206237d7149c27bc3')) >>> decrypt(r, b2a_hex('b537a06cf3bcb33206237d7149c27bc3')) '' >>> r = encrypt('abcdefghijklimabcdefghijklmn', b2a_hex('b537a06cf3bcb33206237d7149c27bc3')) >>> decrypt(r, b2a_hex('b537a06cf3bcb33206237d7149c27bc3')) 'abcdefghijklimabcdefghijklmn' >>> import md5 >>> key = md5.new(md5.new('python').digest()).digest() >>> data='8CE160B9F312AEC9AC8D8AEAB41A319EDF51FB4BB5E33820C77C48DFC53E2A48CD1C24B29490329D2285897A32E7B32E9830DC2D0695802EB1D9890A0223D0E36C35B24732CE12D06403975B0BC1280EA32B3EE98EAB858C40670C9E1A376AE6C7DCFADD4D45C1081571D2AF3D0F41B73BDC915C3AE542AF2C8B1364614861FC7272E33D90FA012620C18ABF76BE0B9EC0D24017C0C073C469B4376C7C08AA30' >>> data = a2b_hex(data) >>> b2a_hex(decrypt(data, key)) '00553361637347436654695a354d7a51531c69f1f5dde81c4332097f0000011f4042c89732030aa4d290f9f941891ae3670bb9c21053397d05f35425c7bf80000000001f40da558a481f40000100004dc573dd2af3b28b6a13e8fa72ea138cd13aa145b0e62554fe8df4b11662a794000000000000000000000000dde81c4342c8966642c4df9142c3a4a9000a000a' """ l = len(v) #if l % 8 != 0 or l < 16: # return '' prePlain = decipher(v, k) pos = ord(prePlain[:1]) & 0x07 + 2 r = prePlain preCrypt = v[0:8] for i in range(8, l, 8): x = xor8B(decipher(xor8B(v[i:i+8], prePlain), k), preCrypt) prePlain = xor8B(x, preCrypt) preCrypt = v[i:i+8] r += x if r[-7:] == b'\0' * 7: return r[pos+1:-7] def decipher(v, k): ''' TEA decipher, decrypt 64bits value with 128 bits key. it's the inverse function of TEA encrypt. ''' n = 16 y, z = map(ctypes.c_uint32, struct.unpack('!LL', v[0:8])) a, b, c, d = map(ctypes.c_uint32, struct.unpack('!LLLL', k[0:16])) delta = 0x9E3779B9 s = ctypes.c_uint32(delta << 4) for i in range(n): z.value -= ((y.value << 4) + c.value) ^ (y.value + s.value) ^ ((y.value >> 5) + d.value) y.value -= ((z.value << 4) + a.value) ^ (z.value + s.value) ^ ((z.value >> 5) + b.value) s.value -= delta return struct.pack('!LL', y.value, z.value) ================================================ FILE: requirements.txt ================================================ rsa requests ================================================ FILE: setup.py ================================================ from setuptools import setup, find_packages setup( name='qqlib', version='1.1.1', description='QQ library for Python.', long_description='QQ library for Python, based on web APIs.', url='https://github.com/gera2ld/qqlib', author='Gerald', author_email='i@gerald.top', license='MIT', classifiers = [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.0', 'Programming Language :: Python :: 3.1', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', ], keywords='qq', packages=find_packages(exclude=['tests']), install_requires=[ 'rsa', 'requests', ], ) ================================================ FILE: tests/__init__.py ================================================ ================================================ FILE: tests/test_hieroglyphy.py ================================================ import unittest from qqlib import hieroglyphy class TestHieroglyphy(unittest.TestCase): def test_decode(self): for encrypted, plain in [ ( '(+[]+[])+(+!![]+[])+(!+[]+!![]+[])+(!+[]+!![]+!![]+[])' '+(!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+[]' ')+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!' '![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+' '!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]' '+!![]+[])+(+{}+[])[+!![]]+([]+{})[!+[]+!![]]+([]+{})[!' '+[]+!![]+!![]+!![]+!![]]+([][[]]+[])[!+[]+!![]]+([][[]' ']+[])[!+[]+!![]+!![]]+(![]+[])[+[]]', '0123456789abcdef' ), ( '(!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![' ']+!![]+[])+(+[]+[])+([][[]]+[])[!+[]+!![]]+(!+[]+!![]+' '!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+' '([][[]]+[])[!+[]+!![]+!![]]+(![]+[])[+[]]+(![]+[])[+[]' ']+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})' '[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+([' ']+{})[!+[]+!![]]+(+{}+[])[+!![]]+([]+{})[!+[]+!![]]+([' ']+{})[!+[]+!![]+!![]+!![]+!![]]+(+!![]+[])+([][[]]+[])' '[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[' '])+(!+[]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]]+([' '][[]]+[])[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+[]' ')+(!+[]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+[])+(!+[]+!' '![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+' '!![]+!![]+!![]+[])+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(' '!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]' '+[])+(![]+[])[+[]]+(![]+[])[+[]]+(+{}+[])[+!![]]+(!+[]' '+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![' ']+!![]+!![]+!![]+!![]+!![]+!![]+[])+([]+[][(![]+[])[!+' '[]+!![]+!![]]+([]+{})[+!![]]+(!![]+[])[+!![]]+(!![]+[]' ')[+[]]][([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![' ']]+([][[]]+[])[+!![]]+(![]+[])[!+[]+!![]+!![]]+(!![]+[' '])[+[]]+(!![]+[])[+!![]]+([][[]]+[])[+[]]+([]+{})[!+[]' '+!![]+!![]+!![]+!![]]+(!![]+[])[+[]]+([]+{})[+!![]]+(!' '![]+[])[+!![]]]((!![]+[])[+!![]]+([][[]]+[])[!+[]+!![]' '+!![]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!![]' ']+([][[]]+[])[+!![]]+([]+{})[!+[]+!![]+!![]+!![]+!![]+' '!![]+!![]]+(![]+[])[!+[]+!![]]+([]+{})[+!![]]+([]+{})[' '!+[]+!![]+!![]+!![]+!![]]+(+{}+[])[+!![]]+(!![]+[])[+[' ']]+([][[]]+[])[!+[]+!![]+!![]+!![]+!![]]+([]+{})[+!![]' ']+([][[]]+[])[+!![]])())[+[]]+(!+[]+!![]+!![]+!![]+!![' ']+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!!' '[]+[])+(!+[]+!![]+!![]+[])+(+!![]+[])+(!+[]+!![]+!![]+' '!![]+[])+(+{}+[])[+!![]]+([][[]]+[])[!+[]+!![]]+(!+[]+' '!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(+{}+[])[+' '!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!!' '[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+[' '])+([][[]]+[])[!+[]+!![]+!![]]+(+[]+[])+(!+[]+!![]+!![' ']+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!!' '[]+!![]+[])+(!+[]+!![]+[])+(!+[]+!![]+!![]+!![]+[])+(!' '+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(![]+[])[+[]]+(!' '+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+' '!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]' '+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!' '+[]+!![]]+(!+[]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!![' ']+!![]+!![]+!![]+!![]+!![]+[])+(![]+[])[+[]]+(!+[]+!![' ']+!![]+!![]+!![]+[])+(!+[]+!![]+[])+([]+{})[!+[]+!![]]' '+(+[]+[])+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!+[]+!![]' '+!![]+!![]+!![]+[])+(!+[]+!![]+[])+(![]+[])[+[]]+(!+[]' '+!![]+!![]+!![]+[])+(![]+[])[+[]]+([]+{})[!+[]+!![]+!!' '[]+!![]+!![]]+([]+{})[!+[]+!![]]+(!+[]+!![]+!![]+!![]+' '[])+([]+{})[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+' '!![]+!![]+!![]+[])+(+{}+[])[+!![]]+(!+[]+!![]+[])+(+!!' '[]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!' '![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+' '!![]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]]+(' '[]+{})[!+[]+!![]+!![]+!![]+!![]]+(!+[]+!![]+!![]+[])+(' '[]+{})[!+[]+!![]]+(!+[]+!![]+!![]+!![]+!![]+[])+(!+[]+' '!![]+[])+(!+[]+!![]+[])+([]+{})[!+[]+!![]+!![]+!![]+!!' '[]]+(+[]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+(+{}+[' '])[+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(![]' '+[])[+[]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])' '+([]+{})[!+[]+!![]+!![]+!![]+!![]]+(!+[]+!![]+!![]+!![' ']+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+[])+(!+[]+!!' '[]+!![]+[])+(+[]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!!' '[]+!![]+!![]+[])+(+{}+[])[+!![]]+(![]+[])[+[]]+(!+[]+!' '![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+' '!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+' '[]+!![]]+(!+[]+!![]+!![]+[])+(+[]+[])+(+[]+[])+(!+[]+!' '![]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]]+(!+[]+!' '![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+' '[])+(!+[]+!![]+!![]+[])+(+{}+[])[+!![]]+(+!![]+[])+(!+' '[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(![]+[]' ')[+[]]+(!+[]+!![]+!![]+!![]+!![]+[])+([]+{})[!+[]+!![]' '+!![]+!![]+!![]]+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!' '![]+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+' '[])+(![]+[])[+[]]+([][[]]+[])[!+[]+!![]]+(!+[]+!![]+!!' '[]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]+!![]+!![]+!' '![]+[])+(+!![]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]' '+!![]+[])+(+[]+[])+(!+[]+!![]+!![]+!![]+!![]+!![]+[])+' '(![]+[])[+[]]+([]+{})[!+[]+!![]]+(!+[]+!![]+!![]+!![]+' '!![]+!![]+[])+([]+{})[!+[]+!![]+!![]+!![]+!![]]+([]+{}' ')[!+[]+!![]+!![]+!![]+!![]]+(!+[]+!![]+!![]+!![]+!![]+' '[])+(!+[]+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])+(!+[]' '+!![]+!![]+!![]+!![]+!![]+!![]+!![]+[])', '290d56eff8b7babc1d85bd63477c46ffa89h96314ad9a783e06824' '7f9666b49f52b0c52f4fcb4b9a21798bc3b522c06a7f8c83309af9' '36b3006b833a19f5c98fd941806fb6cc588' ), ]: self.assertEqual(hieroglyphy.decode(encrypted), plain) ================================================ FILE: tests/test_tea.py ================================================ import unittest from binascii import a2b_hex, b2a_hex from qqlib import tea KEY_1 = b'aaaabbbbccccdddd' DATA_1 = b'abcdefgh' ENC_1 = b'a557272c538d3e96' KEY_2 = b2a_hex(b'b537a06cf3bcb33206237d7149c27bc3') DATA_2 = b'' ENC_2 = b'b56137502728e2c74bb84c6d50d21973' class TestTEA(unittest.TestCase): def test_encipher(self): c = b2a_hex(tea.encipher(DATA_1, KEY_1)) self.assertEqual(c, ENC_1) def test_decipher(self): c = tea.decipher(a2b_hex(ENC_1), KEY_1) self.assertEqual(c, DATA_1) def test_decrypt(self): c = tea.decrypt(a2b_hex(ENC_2), KEY_2) self.assertEqual(c, DATA_2) def test_encrypt(self): e = tea.encrypt(DATA_2, KEY_2) src = tea.decrypt(e, KEY_2) self.assertEqual(src, DATA_2)