# coding=utf-8

import re
import json
import logging
import os
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
from logging import handlers
import crcmod

BASE_DIR = os.path.abspath(__file__)
LOG_PATH = os.path.join(os.path.dirname(BASE_DIR), "logs")
if not os.path.exists(LOG_PATH):
    os.makedirs(LOG_PATH)


def get_xml_header(xml):
    xml_header_re = re.match('^<\\?xml.*\\?>', xml)
    if xml_header_re is not None:
        xml_head = xml_header_re.group(0)
        return xml_head
    return ''


def xml_parse(xml):
    xml_header = get_xml_header(xml)
    xml_body = xml[len(xml_header):]
    xml_body_re = re.match('.*?<root>.*</root>', xml_body)
    if xml_body_re is not None:
        xml_body = xml_body_re.group(0)
    else:
        xml_body = None
    return xml_header, xml_body


class AESBCBEncrypt(object):
    """
    AES-BCB模式加密解密，PKCS7填充方式
    """
    def __init__(self, key, iv):
        self.key = key.encode()
        self.iv = iv.encode()

    def pkcs7padding(self, text):
        """明文使用PKCS7填充 """
        bs = 16
        length = len(text)
        bytes_length = len(text.encode())
        padding_size = length if (bytes_length == length) else bytes_length
        padding = bs - padding_size % bs
        padding_text = chr(padding) * padding
        self.coding = chr(padding)
        return text + padding_text

    def encrypt(self, content):
        """ AES加密 """
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        # 处理明文
        content_padding = self.pkcs7padding(content)
        # 加密
        encrypt_bytes = cipher.encrypt(content_padding.encode())
        # 重新编码为16进制
        return b2a_hex(encrypt_bytes)

    def decrypt(self, content):
        """AES解密 """
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        text = cipher.decrypt(a2b_hex(content)).decode()
        return text


class SingletonMeta(type):
    instance = None

    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super(SingletonMeta, cls).__call__(*args, **kwargs)
        return cls.instance

    def __new__(mcs, name, bases, dct):
        return type.__new__(mcs, name, bases, dct)

    def __init__(cls, name, bases, dct):
        super(SingletonMeta, cls).__init__(name, bases, dct)


class ExceptionLoggingMiddleware(object):
    def __init__(self, get_response):
        self.get_response = get_response
        self.apiLogger = logging.getLogger('')

    def __call__(self, request):
        try:
            body = json.loads(request.body)
        except Exception:
            body = dict()
        body.update(dict(request.POST))
        response = self.get_response(request)
        if request.method != 'GET':
            self.apiLogger.info(
                "\nuser: {}\n{}\n{} {} {} {} {}\nreturn {}".format(
                    request.user, response.renderer_context["view"],
                    request.method, request.path, body, response.status_code,
                    response.reason_phrase, response.data))
        return response


class Logger(object):

    __metaclass__ = SingletonMeta

    logger_dict = {}

    def __init__(self, level="DEBUG"):
        self.level = level

    def get_logger(self, module, filename):
        if module in self.logger_dict:
            return self.logger_dict[module]
        logger = self.create_logger(module, filename)
        self.logger_dict[module] = logger
        return logger

    def create_logger(self, module, filename):
        LOGGING_MSG_FORMAT = "%(asctime)s [%(levelname)s] localhost " \
                             "[%(funcName)s] %(pathname)s:%(lineno)s " \
                             "%(message)s"
        LOGGING_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
        logging.basicConfig(level=self.level,
                            format=LOGGING_MSG_FORMAT,
                            datefmt=LOGGING_DATE_FORMAT)

        logger = logging.getLogger(module)
        handler = handlers.RotatingFileHandler(os.path.join(
            LOG_PATH, filename),
                                               maxBytes=1024 * 1024 * 50,
                                               backupCount=5,
                                               encoding='utf-8')
        handler.setFormatter(
            logging.Formatter(LOGGING_MSG_FORMAT, datefmt=LOGGING_DATE_FORMAT))
        logger.addHandler(handler)
        return logger

    def set_level(self, level):
        self.level = level


def getLogger(module, level="DEBUG", filename='industrial_gateway.log'):
    log = Logger(level)
    logger = log.get_logger(module, filename=filename)
    return logger


def getLoggerForlbzy(module, level="DEBUG", filename='lbzy_logger.log'):
    log = Logger(level)
    logger = log.get_logger(module, filename=filename)
    return logger


def crc_modbus(content, left_high=True):
    """modbus crc校验码，left_high=True表示高字节在前"""
    content = content.replace(" ", "")
    crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
    crc = hex(crc16(a2b_hex(content)))[2:].zfill(4).upper()
    if left_high:
        pass
    else:
        crc = crc[2:] + crc[:2]
    return crc


def signed_int_value(signed_int, bit=32):
    """带符号整型的16进制字符串转化成值"""
    pos_max = 2 ** int(bit-1) - 1
    value = int(signed_int, base=16)
    if value > pos_max:
        value -= 2 ** bit
    return value


def signed_int_hex(signed_int, bit=32):
    """带符号整型的值转化成16进制字符串"""
    length = int(bit/4)
    value = hex(signed_int & eval('0x'+'f'*length))[2:].zfill(length)
    return value


if __name__ == '__main__':
    aes_bcb = AESBCBEncrypt("fromhdsegtoacrel", "fromhdsegtoacrel")
    # raw = b'\x1f\x1f\xf2\x00\x00\x00 0~m\xd1\xa1wpQ\x86o\x19\xbb&\x10T6:Q|K\xa9rc\x85\xebU\x05f:\xce\xe8l'
    d1 = b'\x1f\x1f\x03\x00\x00\x0f\xb0\xd9\xbb\xd8\x06\xc4\x10^\xe4\xb5\x169\xa4\xbc\xafse\xaf\xe9\xc1\x88\x82\xd0\xa8r\x7f\r\x17\x8a\x1by{\xba\xa12?\x02\xc9M \xa6\xcf\'P\xa5\x9f\xe9\xd3\x14s\xee\xdb#\x87\xbe=l,\x18h3-\x1a\xcf\xdd\x00$\xda\xa1\x11\x15\xef\x0e\xdd>L\xb8\xb8\xe2\x8d\xb38\xc7\xcf\xcd\xc4z\xf7;{C\xe6\xb4I\x02f\x0e\xf3\x9eQSa\x0cZ\xf4\x8a\xb6\xad\x13\xf7\xe4fc5\xdb,\x0c\x90\xbe\xbf*\x1d\xba\xc1\xc6\x9f\x04\x7fo\xdd\x12\x08\t\xab/\xe7\x06/\xee\x97YS\xbe\xe4P;\x1d\x1b\xa5~Q\xe3\xef\xe7\x0e2\xe6\xe4\x16\xe3\xc1\xb7Z]\x11j3\xafd\x17\xd6\xf8\x81\xbc\xb0\x8e\xf1\'\x95\xe7P\xda\x8d\xff%\xbaw\x1e\x8d\t\xe7\xaa\xa54\x8c\xd2\xed\xdc\xfb\xecY\xc6>f:\x03\x9f\xde\xf0\xfb\xe8\x96}\r\x04A(\xc4,\xb6\xcb\x8drD\xa8\x14\xfdU\x9d0\x16\t\\\xc8u\x18\x14\xcc\\\xb3\xf2\xa7$\xd2\xd1~\xdf\xae\xa8u\xea\xe5\xec\xe99v*\x92\xdd\x17 \x13uR5\x9f\xc4\xc4\xc8J=\xbbD\x01\xbb%$v\xd6i\x04[\x8f\x00\xbbOH6\x08B\xdd\xcc\xf5\x8f}\'$[\x88\x83\xe5+L\xf1$\xed\x9d/\x1c\x14ehr<\xa1\xc3\x1e\xe8f\xdc\xd6K7}\xda/x\xeaJ@\xc4\x8b\x11\x17\xba\x0c\x1b\xe9\xa0\xbe\r\n\x9a\x00Ne:R\x93\x81\xa6\x8c\xcb\xa3\xe4\x16\xd9\xe4\xd6&\xe6\x9b\x9f\x87^\xe5\x8a\xc3\x8c\xade\xbd\x86U\xad\xd9\x84\x8f1\xd2\xaf\xe1\x01\xd4o\x06WU\xe1@|\x1a6\x9d\x0b\xa3\xb13`\x99-\xbc\xc5\x13Y\x13\n\x8eMT\xc9H\x8b\x8eu\xc91|\x01jrBx\x02\x92k\x86li\xc9\xe6\xeb\xae \xced\xbc\xb4\xd1q\x0e\x9b\r*\xb0\x8eh\xa1\xfd\x1dF\xe4\x81C\x87G8BDe\xdd\xb9\x1a\xc3\xbc\xb7\xb3\x80\x86\xb8\xc3[\xfcB\xc54\xad\x8a*Nb^\x86\xf9\xe5Z\x9a\xe80\xb1\xb6\x8c\x19\xc67}f\xeb\x86`s\xf9\x91A\x98_L\xd5C\xd8=)\x0bg\x7f\xf5\xa6\x80.\x8b\xb7]\xc8\xb2}\xae\xbf\'R\xb7Y\x9bt\xf8\xe9\x15\xd3\xf8\x920\xa8\xac\xd7=\x17"\xa5\x8d(\xa9\x82!\xb9\x05x\x92\xdf\xb2r\xf3\xe6f\t\x03\xff\xb0\xe8\xeb\xac\xdf\x13U;\x92c\x0f\x9cZ\xe5\xea8[\x02Y\xe3\x165_\'\xb2\x86HL\xc5\xbf\x87\xba:\xa2hj\r\xbaw\xe7\xb3\x14\x90\xf7WT\xc3\x1f}\xa0\xb4\x04%t\xbf\'Dh\x8f\xbc\xc2\x0fa\x11\xa7D\xa3\xb3\x1f\xf0\xda\xa9]\xaaDd-\xd7KB\xb0A|\xfak\xdc> \xba\x16\x96DbJ\xed\xb8\xfc\xbb\x9e\xea\x90\xc7E\x87\xcc\x1c\x04\xf1U\xc0\xfa>M5\x1f\xf7\xf0\xcf\x08fTI\x1b\xe4`\xa6\x870A\x94\x13\xdbq\x02\x0c\x8fAR\x87\xb2\xc5\xd7wN\x88\x0bo_ \xd50\xa2\x85#\xfe\xf0!#\xd1[:\xc5\xa8r}\xcdY\xd6\x07\xe7CQ\x0c\xac\xc4\x91\x0e<\xda\xfb\xfeq\x13\xa5\xf8Y\x12\xb2\xe9\xe4\x9fp<\x9e\xe7|\x1c\xf8Z\xcde\'\xf4\xee\xa4h\x8a\xa4\x1e\xba\xf00u\x8e[\x92\x0c\x85\xdd(O\x9c\x92\x9f9\xbeO\xc1e\x9a\x1c\xf7\x0f3umG\xcaC\xe4\xa8\xdc\x97\xf9\xf1\x05\xfcK\xadsl\xd3d\xbeD\xf8\xbdkz\xdf\xcbe\x02\x03\xcd)|\xad\x9e\x17o\xdd`\x82\x15\x1eC\xd2\xe6f\x08Hv\x12\xbe\x86@\xb4F\x89E\xf9\xe6+\xae\xe8b,\xc6\xac\x89\x8f\xfb\xbf\xf0\x18\x86K\x1d\xfb\xd5\xae3t\xd7\xc0\xd4\xb2\xa4\xae\x14\xe4q\xea\xb4\xc6V\xcb\x04\xd1\xee\xec[\x82\x88Fb\x90!\x1b\xe2\x91\xd3\xc7\x00\x98\x0f\xb5\x81\xcd\xe9\x15\xd1OW\n\x1d\xc6\x80\xc1\\I(\xdc\xc5\xe8@\x0c~\xc6;,\xbd:+\x1d\xd7"e\xff\xcf\xed\xd8\x04\x9a\xaf\xd7l\x07\r\xf2\x19\xec\x9bO\\\xfc\xe0\xb24IGn\xe2\xa0(\xd7\xf4kR+\xa3\\\xcf<\x97J9P\xc6\x19\xef\x97\x17w\xab\xf1;Q'
    d2 = b'\xcf38w\xac\x88gG8Q\xf6\xfe\x8b\xc1\',N#\xd1G\x0c\xcd\xc7\xaa=\xd0\x97,\x8fj+\xc5ak\x0c\x97$\xca\xd58\xedT\x89\xa4\x17\x92.\x81\x84og:!\xaf\xed\x9e\xe4Yk\xe0U<\xb1\x10$\x84/:O\xe6J\x14\x04\x8f&\xaa\xbe\xfb\xab\xf4Z\xd3\x7fC\xaee\xad\xe5\x12\xd9\x12$\xbd\x85\xe3\x86\xec\xf6s\x8f\x9e\xb5\xb1c\xa5\xe1\x08\x81\xf4\x15\xdc\t)\xfbQ\xc5&\xd1R\xef\xf6/\xa8 \x04\xda)o\xcc\xfb\xc6\xfe\xd6Fi_\xfdF\xa1\x19\x81\xb7\xcb\xb9\x9a\xcb\xb3%?\x981\xf6\xe1\xe9\xf9[\x16\xc0\n"Gp\x0f\x86;\xe1r\xe3d"\x99_\xb8\x85\x86\xb5x\x15\xbfy\xbe\x01\x8e\x93&\xce\x97\x17\xcdc\xd9\x9e\x1c\xa0(-\xcc\x9a\x98\x8fSJ6\xf9S\x11\xb6\x9f%\xd6D\x06\xd7\x1d\xcc\x01\xcd\xf6\xea\xb1\xa4\xd9\xa3\xcb\xa5*\xd8\x12\xc3\xe9\xe2\xf7\xd7\r\xacF\xcaw\x1b`.\xe5\xeb\x0f\xfed\x07j\x87B\xc0x\xd5\x08ZE\x02Jk:\xcc6\xa4\x9e1o\xc5c\xbe\x94Qh\xc0\xb1\x15*8\xd7VC\xa3\xea(G\x80\xbf\x1e\xa3\xc9\xb8HM@\xdeZ\x19\x8d\xd2\x8cT\x86\xecW\x0b\xdak~\x82\xaf\x82\xac\xbdf\t\x15]\x18\x9a\xbbA\x91Q\xe0x\xd0\x12\x9a\x89\x96\xberu\x10h\xf5\x04M \xd755\xa3+\n\x1c\x15\xde\xb1:\xd5\x81 g\xc1t\xde\xac\xd4:\x047\x9eZ\xff4s\xa0m\x9b}h\xa8:!\xfe\xf1I\r\xa3\xfca\x9a\x9b\xe1\n\xfax.\xde^cy\xbf\xc7H\x85-J\xbaW\xfe\xc9\xa7j~\xc8`B\x03\xf2\x19\x91\x94\xe1$\x92\x85\x82w`\xa4c\xbd[\xcbh\xbcx`\xf6\x95\x89\xe4i\x02\xe2\xb5}\x03xC\x04\x16"\x04\xd3}mx\x06\x05\xaa\x9fK(\xb5\xd6\x07-\xb1\x8a\x88\x7fW\x18\xbd\xc9w\xfb\xf3Wj\xebMI\xda\xdd6\xa5+\xaf \xd2\xb8\\0os\x91m$~\x9f}\xf2\xde\xd9G\xd2\x0b\x1e\xa0\x14S\xa6\'\xb6\xaa\xdfS\xdd]\x98$\xc8\x892\x15y\x13L\x86\xbf\xb4\x0c\x82\xcf?\xc2,\xff=t\xab\xa5\xb4\xc2\xc0fJ56:4\xf6\x96w\x81\x9d\xd5V7i\x7f\x1a"\xa8R\xd1V:s\x0e\nWk\x9e\xf7\xe1m\x0b\xbb\xbb%\xfa3-\xbb\x00rQ\xda?#+\xc6?U\xbc\xfd\xe5\xf4]J\xf2Y\xfc\xe5d\xcf\xc9c@\xdaB\xf8\x05\xdd[?\xa7#\x830\xb6\x0c\xbf\xd1d\xfb\xc1\x86\xf1\x8dTI\xf7\xc7G\xe4\x03\xa9\xa3\xa84e\x92\xe6\xa2\xed\t\x84(AU\x0f\x89\r\xa9?\xc3\xe4\xe8\x84\xa22\xa8i\xff\xed\x8c\x95\xaf\xcbyV@z\xd6\x91\xcd> r\xf6\xf7DK\xcdOY\xbf\xff\xadX)(*\xf7\xb6\x17\x91f\xa6\x9e\x9ck\x06@\x0b\xd5\x8e3Y0\x0b:\xc8\xe5\x0eE\xe4\xec\x04\xec}q1\xf3\xb0\x9c\xb5\xf3x\x97wi\xf9\xde\x13\xde\xc0\x96\n`\x97\xe7\xd5\xff\xa8JD+\xed\xaa&\xb1\x08-k\x859|\x0e\xf5=t+\x15\x0b\xf0\xa7\xe7\xa4\xf4Pt\x03M#\x88<q\xb6\xb7V\xb3\xa7\x83\xb0\xb6EUXS{\x13\xf2\xa3\x13\x1b\xb7\x82\x16fl\xb1\xa9\xce:~\xcd\xe4\xf4\xefU\x9b\xc4\xe1Zk \xf2LDp\xde\xf9\n\x90\xebg\x89\xf2\xae\xd0\xf6\xde\xce<\xe1\x91s\'\t7 J\xe4\x1b\xfd2\xd6\xdd\xe3\xf4\x03pO+\x8f\x93\x16\xc3%T\xba\xb2x\xb1\x88Q:\x0f\xb4\x89\xd3\xadn\xfb(m\x9f2N\xbb\x9f\xd8|=v\xc4\xc8\xddkq\x7f\x90\xf2\\$|\xe5\xfe\xe3n\x07\xb7\x0f\xb4`\x88\xdfIFIeh\xaf\xc4^,\x84\xb1g\x14\x04\x1d(\xd7\xdc%\xba\x1c\x19H\xad\xda\x84#\xb9\xa3\xd06\x9cC\xa6\x92\x01\x10\xc5\xf3n\n\x1c\xd0\x15\xa2q\x1c\xe3\x911\xa4\xa4\xf4g\xb8\xf9\xe89\xe0\xb8G\x10\xda\xb6\x9dB\xef\xf8CaE(\xba\x07\x96\x81\x96\x07z\xf2\xed!\x18\xacim\x08\xd5\x1fh\xaa\x8b!\xafO\xad\x01'
    d3 = b'\x98s\x16\x06\x829\xb8H\xd9\xb9\x057R\x86\x96\xc60\xf7}\x13\xdd\x9e\x1d}\xbdX\xab\x83\x91\xd4\'c\xd26\xa6\x03\xd5)l\xb7r\xb0\x90\x0f\x9c>\xde \x7f\x90\xb1a\x9e\xacb\xc4\xea&\x1f\'M\xdb\xff\xe3\xde\xa7\xf7\x9b\x8d[\x15\\I`\x8e\x88\xcb\x83\xcc\xdb;\xbbo\x93\x92\xadI\xc3`OM\xb0\n\x1f\x0e2\xb9o(\xc7d\xad\xc6\xcfl\xe8\'\xec\xe7\x0b/\xcf%\xc1\xd3)\x98.\xf6\x93@\xbd\xa3\xf5\xb0j\xd5?\xe6:]\xd3\xd3\xc6\xa4\x08\xdeY\x0c\xd2\xdf\xd5I\xcd\xb4\xb6\xa5\x94\xaan\x89\x82/*\xc2\xbf\x1d\xa0O\xc4\x92\xaay\x9aE\xa7\xbb\x15\x14k\x10\x11\x94\rQ\xc1\xdb\x80\x92cOms\xe1\x02\xbec{\x1e\xad\xe6\xaf\xe3!A\r\x0b4\x98Q-\x9e\x08\xee\xa8\xde\xfc\xd6\x93\x94\xc2%\x9c\xc3\x03\xad\xec\x18*\xde\xd2\xe5\xcbf\x0fJO\xcd\x9dg\x84\xbdI\x8b\xa3\xf3\xfc\x9da\x1dj\x99y\xdd\xbcm\x04\xda@U\xb8\xb4\xa3\x1b\xae]79\xe6\xf8\xb4aM\xbb_A\x9df\xad\x01\x1d\xa3\xa0dPC\xc3&\x81\xe9\x90\xdc\xab\xc0\x8e\xa0\xaa\x0f\x92\x18\x9f\xdd\x12\x8c\x82#\\\xdbu=\x1b\xe5\x1b\x0c[\xf9\xe4\xd2w\x9fsML\x80g\xa8?\xf0T`\'\xff\xd6@\x1e|\xe2\n\x02\xc1M-W\x1cf\xa2\xeb\xf3|\x8c5\xe9\x07\xcd\x08*\x9eiO\x1d\xa2>1\x0bF^\x95\x95_)M"\x03F\x01k\xeb\n\x90\xc1\x0bJ\x99gc<\x17i\xf9\xc2\xdf\xdaA\xd5\xbc\x01O\xceYL/I\xcb\xf5M?T\x14bs\x86\x12\xc3\xa2\x13\xe5\xa1`\x1c\x88]c\x13\xfa|\xd37\xac\xbd\xe4,\x858\x0b\xc4\xfa\xe1\x19@\xa2\xf7\xc8V\xec$\xe7\xbdG\xd9&.\xca\xf7\xf92\x19\x0b&\x8a\xa9wH\x18z!\x9e\xe3\xa6\x89D\x868?\x01L\x8a\xb1.m\x93Y\x8c<\x867}\xab\x85\\\x1a\x1a\xd78F\x9e\xdd\xbaq\x8a\xb1l6\x85\xb1\xc4vrj\xf3\x84\x9b\xc0%\xae\x0b\x99i\xa8\x87\x8b\xa3\xec}\x9b\x10\x84\x85\xe0~\x80\x07\\\xb9\xb4\xfa)\xe9|u\xf8M\xf9\x97s\xa5\xb3d\xac\xa9:\x91\xfc\xbbrz\xfd\xe1\xaf\xcd\x8e\x1ck\x94+F\x11\xe4\x87\x12\x8e%\xb8\xe1U\x89\xf6\x8c\x91V\x1am\xd74\xc2\xcf\x91\xf5\xc3U\xf8\xc4\xbe\x84\xe93\x15!]P\xfa\xd1J\xdf\x89\xeb\x87\xf63\x98\xd6\xbe\xf8\x91\xd2\x06\x1b\xbc\x02\xd1N\xd21\xcb\x0btw\rd\x8e\xe8\x06\x84\xe5\x9ec-5\xbd\xe4<\xe3\x07\xe7\xba\x05U6j\xdcp@j\x9f\xc6>\xbe\x18\nR-\x1c+\xca\xf1\x00\xf2\x0f\xc6\xc1\x95\xe2\xb6\xf0\xf3\x06\xb1@\xa4G,-f(\x9e\x98Z\xa7{\x00\xa0\xbcDX\\[\xf9j\xe5\xae\x82\x0f\xc09\xceCM\x80|\xd8\xb0\xa0\x95\x1dK\x0c\xf3x9^c\x19%k\xbc$Kzm\\"D\x83\x92\xc6.U\x9f\x89\xd9;E\x1e\x91)\xfc%7WjZx%\xc19\xf6\x9b\xda\rc\xa3!\xc6^q 6FQ8\xc8{\x89\x85\xf0\x97\xe3\xbf?\x7f\xa1&\x8bs{\x16\xac\x84/W}\xdftB%\xff\xea\xea\x9f;=\x12\xe9\xdc&\x85W\xd6L\xb9\xc5\xa9\xe8n\xf13\xe2aW\xd7\x16\x96w/\x00{\x19Q\x8e}\xe9\xb6\xcd\x18\x84f\xf7\x11Y&\xe8\x1d\xe4\xab\xc9\x9a\xa4\xbd\x1f\x07y\xbfB\xbe8\x14\xf1\xfc\xb3Y\xa8\x80\x81\xe9[\xf1{\'\x8e<R*>;\x05\xa0\xce\xbbV\xcf\x02\x8a\xb7\xd2\xbd\xc8\x19_\xb2\xc5\x81\xb9\x8f\x8f~ \x8e\xc1\xe1\x82r\xb0\n\x9d\x11\xe6\xd0\xfc;%\x1av\xb0\nxZ:\xf2\xa6\t\x8a\xb8Q\xca\x85W\xf7\x8a\x07\x83\x1e\x8e\xf5\xf6g\xf6\x96\x7fd\x9bWe^\xb3\xd3\xf7\xd0\x0fr\xa6\xc1\xf3\xb09\xda\xcc\xa3{R~Z\x8b\xf5\xa2\xee\xc0\xd9N~\xcf\x88^$N~h\x97Eg\xaf[\xb4\x11\x93\xcc\xb0:\x88UL\xec\n\x1a\x15\x1eT\xbf\xe1x\x08\xffm\xc5bB\xdf\xaez+\xb2\xfa'
    d4 = b'?M\xb5\x01\xb4t\xbch?ojP\xbaX!\xe2\x8f\xa0\xaf\x8b\xad\xdb\x99\xb3E\xf2;\xef,c\xb6\xb4\xbd>\xf8\x02Ii\xf7O\xe4\x91\xb2a{\x7f\xecvJT\xd62\xe0A\x80D)\x07\xf71\x040\x94\xbe!t\xa1\xcd\x95\xd6Et8!Fr\xce9G`z.:7\xe5\x10n\xb8\x01C\xaa\x97\xd6\x96\x9dij\xe3 \x16\x81\x86&\xa0\x13Q\xf0=\xb9\xb3\x95hU\xf0\xae\xab\x93\xc4ip\x16Q7\xe0\x89i\n\x14\xf18\xe5\xebC\r\xdb\x85X\x18\\\xc7\x95Q*\x0f\x9a\xfa\xce\tf\x06cB\x95\xdc\xf6\x89~\x17\xdf\x1fJ;\xdaS\xaf~\xd9T\xf2\x93\xce\x1f\x98\x1d\xf6\\\xf8\xf2\x16\x96`\xb94F\xf9\x9602Qb\x80f\x03o\xc0B\x80\xa6\x96-\xd7\xd7_\x00t\xf3\xaeV&\xbc\x06\xe9j|\xe2-\x1eBz\t\x1c\x92@\xafC\xc2\\\x1a\xa8r\xa7A\x15\x81\xa3\xa7x\x1fb\xf3\xc9V\x0c3\xeaL\x878\'\x8d\x8d\xa4U\xbfV\xb37l\xf6c\xae\xcb4\xdfm \x8b\xccP\x9d\x86\xa8\x95\xa0\xe2\x11a\xb9\\\x9b\x11\xaaRp\x93*\xf5\xbc2\xab\xcf|\xecdgY\xf1\x85Suw\x90\xc7\x8c<\x91\xd9\xad\x0c_&I\r\x97\xb3\x91\\\xf4pF\xf0<FhK\xac\xe2\xfd\x82\xab\xf5\xd0\x0f\x08M\xb8\t\xb5\x06\xd3\xa9\x02\x0f\xc5\x9f\x89\x89\x99\xe6]&\x14\xd3T\xb0\x82\x81\x89m\x8c"M6\x96\x195\xaf\x85\xd2\xa1\xfd!\xc9\xe7:"\xb89d&\xb9F\xf7\x019\x88w\x840\xd9*l\x8d\xc9\x84cP\xef7\xbd$\xa8\xc1\\\x0c\xf9)\xbd\x92\x8c\xb9$\x1f\xcd\xf8W\x01\xeb\xd7\xe5\x17\xc0\x0e\xb9\x19i\xfa\x14\xbc\xd1\x0f\xc2\t\xd3\x8d\x9b\x10\xf3\xbb@PJ\x00\x0c\xee\xac]d\x81\x8c\xdd\x83\x8ca\xfd\xc5\x96\x81|u\xb7\x8f\xe7T\xd5\x868\x9a\xbe7\x1fz\x8c\x9ew7\t\x057\xd57\x1fn\x86\x1f\x04Ol\xa8\xff\xb8U\xcc\xf6D\xe7w\x05\x91\x9e\xc6E\xa0 \xfe\xb7\xaa_\x11)\x08\xc0\x10\xbc\x9bh\xcfy7\x1d\xe5\x12[%\x9e\xea\x0eB\xf9!\xe3\x19/u>\xddJ\xf2k|\xed\xc7\x04\x90t7?\x80\xa4N5j:\xf3\x1c\x9c\x16Kp\xfb\x143o\xfc\xe3\x96G\x9b\xb4]\xf99w\x05\xa2\nwo\x04\xe4\x8e\xdd\x1fc\xa4?\xd0\xd5}~R\x04R]\xd4\x9bS\xa1\x95\x15\x90_\xc9<y\x05\xb2\xe4\xf5V\xe8K(\x9c\x8c\xde\xebA\xb5z\xc18G\x85y\x86\xea\xb9\x899\x91\xda\xf4\xb3\x93\x15/\x12\x10Wk f\x07\x05\xcc\xadk\xf5)=\xd6\xbb\x08\x18\x1e\x99)\xfb\x84\x85\x1f\x89IhX\xda\xc4\xab&\xfd-`F`Kle\x8c\xce5\x96\x86\x81\xbfF\x0f3p\xbc\xa5"\x17%]\x1e\xe7\xb5\xae3\xe1}M\x1f\xf6\x1f\xbe\xdf\x8d\x1dampK\xbb\x93\xc2S,\x0b*\x96\xd3\xdf\x8a\xe0\xed\x88\xc5\x1at\xae4}\x91f\x87*\x962aV\x1c\xa7\xfa\xdd\xc2\x9aP6\xce\xd1\xc1zg8V\xa1\xca$9\xd9\x85\xdbsm\xca\xe6(X\xd6\x17_\xab\x08\xd2\xb5u\xda\xaacS\xc7\x10o\xf0R\x0f\x83\xa0\xd7L\xa3\xa8eR\xdc]"\xdf\xed\xac\xe7qT\xb7\xc0s\x00\'\xf5\xf6m\xcb\xb6\x8fK\xa3\x04s\xb5B\xf0\re\xd4\xf8\xa2M\xbe\xfa\xe27\xff\x1eB\xbeQ`du#\xbd\x92\x06V\xd1\x035\x17$\x95\xed\x81\x9cP\xb5\x9f\xd4\xe2\xc0/D\xc1\x93Z\xf0\x80\x93\xd1\x8b\rY\xc3N\x06Xm\xbdev\x9d\xb6\x99w\xf3\x80\xe4\x92\xb4\xe3\xa2\x99\xd4\xc2\xe5\xcd(\xa6{\xd6\xf6\x91\xb3\x9d\x84\xd9\x014\x05<l"1X\x8d\x1fG\x1d_p\x17\x17v\xafY\xc8\x16\xa9<LG\xac\x9b\xc2\xcbR\xcb\xdc\x1a\x1d\xf7tx(x\x91\xab1\x0e$\xa0\xcb\x06] \xb7RB8\xa8nH\x18\x08\xdd\xdf\xec\xe3*\x9d\x15\xddU\xde\xaa\xf4\x18\x16\x88\xf5\xc3iT \x92\x8e\x1a\x87\r\xba\x8c\xdd\x81\x08\x17\xfb\x8cI\x1f'
    d5 = b'J\x83e\xdc|C^&\x8cl\x8d\x17r3?\x8ex\xff\x07\xbd\xa6\xd4\x90'
    raw = d1 + d2 + d3 + d4 + d5
    body = raw[7:]
    data = aes_bcb.decrypt(b2a_hex(body))
    print()

