示例#1
0
def str2hex(s):
    """
    把一个字符串转成其ASCII码的16进制表示
    :param s: 要转换的字符串
    :return: ASCII码的16进制表示字符串
    """
    return force_text(binascii.b2a_hex(force_bytes(s)))
示例#2
0
def to_base64(data):
    """
    把字符串转换成BASE64编码
    :param data: 字符串
    :return: BASE64字符串
    """
    return base64.b64encode(force_bytes(data))
示例#3
0
def decode(data, length=None, print_output=True):
    new_data = []
    for t in data:
        i = cipher_letters.index(t)
        new_data.append(i)

    data_list = []
    while len(new_data) > 0:
        t = new_data[:4]
        if len(t) < 4:
            t.extend([0 for i in range(4 - len(t))])

        new_data = new_data[4:]
        data_list.append(t)

    new_data_list = []
    for group in data_list:
        tmp_group = ['%06d' % int(bin(t)[2:]) for t in group]
        tmp_group = ''.join(tmp_group)
        new_data_list.append(tmp_group)

    result_bin_data = ''.join(new_data_list)

    decode_str = hex(int(result_bin_data, 2))[2:].rstrip('L')
    # print(decode_str)
    if length is not None:
        # print(len(decode_str))
        decode_str = decode_str[:length * 2]
    decode_str = force_bytes(decode_str).decode('hex')
    if print_output:
        print(decode_str)

    return decode_str
示例#4
0
def to_base16(data):
    """
    把字符串转换成BASE16编码
    :param data: 字符串
    :return: BASE16字符串
    """
    return base64.b16encode(force_bytes(data))
示例#5
0
def to_base32(data):
    """
    把字符串转换成BASE32编码,5个ASCII字符一组,生成8个Base字符
    :param data: 字符串
    :return: BASE32字符串
    """
    return base64.b32encode(force_bytes(data))
示例#6
0
def to_uu(data):
    """
    uu编码
    :param data: 字符串
    :return: 编码后的字符串
    """
    r = binascii.b2a_uu(force_bytes(data))
    return force_text(r)
示例#7
0
def partial_decode(decode_method, data, base_padding_length=4):
    """
    对前面可以解码的数据一直解到无法解码
    :param base_padding_length:
    :param decode_method:
    :param data:
    :return:
    """
    data = force_bytes(data)
    result = []
    while len(data) > 0:
        tmp = base_padding(data[:base_padding_length], base_padding_length)
        data = data[base_padding_length:]
        try:
            r = decode_method(tmp)
            result.append(r)
        except:
            break
    return b''.join(result)
示例#8
0
def bytes_2_printable_strings(data):
    data = force_bytes(data)
    result = ['', '']
    for c in data:
        if PY2:
            c = ord(c)

        if 32 <= c <= 126 or c in (9, 10, 13):
            if c == 9:
                c = 32
            elif c == 13:
                c = 10

            # 去掉连续的空格
            if c == 32 and result[-1] == ' ':
                continue
            # 去掉连续的换行
            elif c == 10 and result[-1] == '\n':
                continue

            result.append(chr(c))

    return ''.join(result)
示例#9
0
def to_base91(data):
    return force_text(b91encode(force_bytes(data)))
示例#10
0
def to_base85(data):
    return force_text(base64.b85encode(force_bytes(data)))
示例#11
0
def from_base85(data):
    return force_text(base64.b85decode(force_bytes(data)))
示例#12
0
def url_safe_b64decode(data):
    return force_text(urlsafe_b64decode(force_bytes(data)))
示例#13
0
def b642hex(s):
    s = base_padding(s, 4)
    s = b64decode(force_bytes(s))
    return str2hex(s)
示例#14
0
def base_padding(data, length=4):
    data = force_bytes(data)
    if len(data) % length != 0:
        data = data + b'=' * (length - len(data) % length)

    return data
示例#15
0
def to_base58(data):
    return b58encode(force_bytes(data))
示例#16
0
def from_base58(data):
    return b58decode(force_bytes(data))
示例#17
0
    def parse(self):
        encode_str = self.data_str
        encode_str = encode_str.strip()
        should_try_list = []
        # 先进行第一层解密
        for m in encode_methods:
            success, decode_str = self.parse_str(encode_str, m, [])
            if success:
                should_try_list.append({'data': decode_str, 'm_list': [m]})

        result_method_dict = {}
        while len(should_try_list) > 0:
            new_should_try_list = []
            for item in should_try_list:
                m_list = item['m_list']
                data = item['data']
                has_print = False
                for i, m in enumerate(encode_methods):
                    tmp_m_list = deepcopy(m_list)
                    self.last_result_printable = True
                    success, decode_str = self.parse_str(data, m, tmp_m_list)

                    if success:
                        tmp_m_list.append(m)
                        if tmp_m_list not in new_should_try_list:
                            new_should_try_list.append({
                                'data': decode_str,
                                'm_list': tmp_m_list
                            })
                    else:
                        if len(tmp_m_list) > 0 and not has_print:
                            has_print = True
                            md5 = hashlib.md5(force_bytes(decode_str)).hexdigest()
                            if md5 in result_method_dict:
                                item = result_method_dict[md5]
                                # 为了避免数据很繁杂,只保留最短路径
                                if len(item['m_list']) > len(tmp_m_list):
                                    item['m_list'] = tmp_m_list
                                    item['methods'] = '->'.join(tmp_m_list)
                            else:
                                if self.calc_printable_percent(decode_str) >= self.printable_percent:
                                    result_method_dict[md5] = {
                                        'data': '%s' % decode_str,
                                        'm_list': tmp_m_list,
                                        'methods': '->'.join(tmp_m_list)
                                    }

            should_try_list = new_should_try_list

        def cmp_method_list(x, y):
            # 按照解码后的数据长度排序,最小的排在前面
            len_x = len(x['data'])
            len_y = len(y['data'])
            if len_x == len_y:
                for index, t in enumerate(x['m_list']):
                    if x['m_list'][index] > y['m_list'][index]:
                        return 1
                    elif x['m_list'][index] == y['m_list'][index]:
                        pass
                    else:
                        return -1
                return 0
            elif len_x > len_y:
                return -1
            else:
                return 1

            # 按使用方法列表的长度排序,最大的排在前面
            # len_x = len(x['m_list'])
            # len_y = len(y['m_list'])
            # if len_x == len_y:
            #     for index, t in enumerate(x['m_list']):
            #         if x['m_list'][index] > y['m_list'][index]:
            #             return 1
            #         elif x['m_list'][index] == y['m_list'][index]:
            #             pass
            #         else:
            #             return -1
            #     return 0
            # elif len_x > len_y:
            #     return 1
            # else:
            #     return -1

        result_method_list = sorted(result_method_dict.values(),
                                    key=cmp_to_key(lambda x, y: cmp_method_list(x, y)),
                                    reverse=True)
        return result_method_list
示例#18
0
    def parse_str(self, encode_str, decode_method, m_list):
        if len(m_list) > self.max_depth:
            return False, encode_str

        # encode_str = deepcopy(encode_str)
        encode_str = force_bytes(encode_str)
        if decode_method in ['zlib']:
            encode_str = force_bytes(encode_str)
        else:
            encode_str = force_text(encode_str)

        raw_encode_str = deepcopy(encode_str)
        if len(encode_str) <= 0:
            return False, raw_encode_str

        try:
            if decode_method == 'base16':
                # 避免无限递归
                # base_list = ('base16', 'base32', 'base64', 'urlsafe_b64')
                # base_list = ()
                if len(encode_str) < 4:
                    return False, raw_encode_str

                encode_str = encode_str.upper()
                rex = re.compile('^[0-9A-F]+[=]*$', re.MULTILINE)
                if self.regex_match(rex, encode_str):
                    decode_str = partial_base16_decode(encode_str)
                else:
                    return False, raw_encode_str
            elif decode_method == 'base32':
                encode_str = encode_str.strip().replace(' ', '').replace('\n', '')
                # 避免无限递归
                # base_list = ('base16', 'base32', 'base64', 'urlsafe_b64')
                # base_list = ()
                if len(encode_str) < 4:
                    return False, raw_encode_str

                encode_str = encode_str.upper()
                rex = re.compile('^[A-Z2-7=]+$', re.MULTILINE)
                # 自动纠正填充
                if self.regex_match(rex, encode_str):
                    decode_str = base64.b32decode(base_padding(encode_str, 8))
                else:
                    return False, raw_encode_str
            elif decode_method == 'base64':
                encode_str = encode_str.strip().replace(' ', '').replace('\n', '')

                # 避免无限递归
                # base_list = ('base16', 'base32', 'base64', 'urlsafe_b64')
                # base_list = ()
                if len(encode_str) < 4:
                    return False, raw_encode_str

                rex = re.compile('^[A-Za-z0-9+/=]+$', re.MULTILINE)
                # 自动纠正填充
                if self.regex_match(rex, encode_str):
                    decode_str = base64.b64decode(base_padding(encode_str, 4))
                else:
                    return False, raw_encode_str
            elif decode_method == 'urlsafe_b64':
                encode_str = encode_str.strip().replace(' ', '').replace('\n', '')
                # base_list = ('base16', 'base32', 'base64', 'urlsafe_b64')
                # base_list = ()
                if len(encode_str) < 4:
                    return False, raw_encode_str
                rex = re.compile('^[A-Za-z0-9-_=]+$', re.MULTILINE)
                # 自动纠正填充
                if self.regex_match(rex, encode_str):
                    decode_str = urlsafe_b64decode(base_padding(encode_str, 4))
                else:
                    return False, raw_encode_str
            elif decode_method == 'base58':
                encode_str = encode_str.strip().replace(' ', '').replace('\n', '')
                if len(encode_str) < 4:
                    return False, raw_encode_str

                rex = re.compile('^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$', re.MULTILINE)
                # 自动纠正填充
                if self.regex_match(rex, encode_str):
                    decode_str = from_base58(encode_str)
                else:
                    return False, raw_encode_str
            elif decode_method == 'ascii_85':
                if len(encode_str) < 7:
                    return False, raw_encode_str

                if PY2:
                    return False, raw_encode_str

                rex = re.compile('^[A-Za-z0-9!#$%&()*+\-;<=>?@^_`{|}~]+$', re.MULTILINE)
                if self.regex_match(rex, encode_str):
                    decode_str = a85decode(force_bytes(encode_str))
                else:
                    return False, encode_str
            elif decode_method == 'base85':
                if len(encode_str) < 7:
                    return False, raw_encode_str

                if PY2:
                    return False, raw_encode_str

                rex = re.compile('^[A-Za-z0-9!#$%&()*+\-;<=>?@^_`{|}~]+$', re.MULTILINE)
                if self.regex_match(rex, encode_str):
                    decode_str = b85decode(force_bytes(encode_str))
                else:
                    return False, encode_str
            elif decode_method == 'rot13':
                # 如果这里不做限制,会无限递归下去
                if 'rot13' in m_list:
                    return False, raw_encode_str
                decode_str = decode_rot13(encode_str)
            elif decode_method == 'pawn_shop':
                try:
                    encode_str = encode_str.decode('gb2312')
                except:
                    pass

                encode_str = force_text(encode_str)
                encode_str = encode_str.replace(' ', '').strip()
                code_base = '口由中人工大王夫井羊'
                decode_str = []
                for t in encode_str:
                    if t in code_base:
                        i = code_base.index(t)
                        decode_str.append(str(i))
                    else:
                        return False, raw_encode_str
                decode_str = ''.join(decode_str)

                if len(decode_str) < 0:
                    return False, raw_encode_str
            elif decode_method == 'decimal':
                if len(encode_str) < 4:
                    return False, raw_encode_str

                rex = re.compile('^[0-9]+$', re.MULTILINE)
                if not self.regex_match(rex, encode_str):
                    return False, raw_encode_str
                # 解码后是 0xab1234,需要去掉前面的 0x
                decode_str = hex(int(encode_str))[2:].rstrip('L')
            elif decode_method == 'binary':
                rex = re.compile('^[0-1]+$', re.MULTILINE)
                if not self.regex_match(rex, encode_str):
                    return False, raw_encode_str

                # 不足8个的,在后面填充0
                padding_length = (8 - len(encode_str) % 8) % 8
                encode_str = '%s%s' % (encode_str, '0' * padding_length)
                # 解码后是 0xab1234,需要去掉前面的 0x
                decode_str = hex(int(encode_str, 2))[2:].rstrip('L')
            elif decode_method in ['octal', 'octal_ascii', 'octal_binary']:
                # 8进制转成16进制的数据
                rex = re.compile('^[0-7]+$', re.MULTILINE)
                if not self.regex_match(rex, encode_str):
                    return False, raw_encode_str

                rex = re.compile('^[0-1]+$', re.MULTILINE)
                if self.regex_match(rex, encode_str):
                    return False, raw_encode_str

                if len(encode_str) < 4:
                    return False, raw_encode_str

                if decode_method == 'octal':
                    # 解码后是 0xab1234,需要去掉前面的 0x
                    decode_str = hex(int(encode_str, 8))[2:].rstrip('L')
                elif decode_method == 'octal_ascii':
                    encode_str = encode_str.replace(' ', '').strip()
                    # 8 进制的 177 转成十进制后是 128
                    tmp_list = list(encode_str)
                    ascii_list = []
                    while len(tmp_list) > 0:
                        tmp_str = ''.join(tmp_list[:3])
                        if int(tmp_str, 8) > 127:
                            tmp_str = ''.join(tmp_list[:2])
                            tmp_list = tmp_list[2:]
                        else:
                            tmp_list = tmp_list[3:]
                        ascii_list.append(chr(int(tmp_str, 8)))
                    decode_str = ''.join(ascii_list)
                elif decode_method == 'octal_binary':
                    # 因为这里有补0的操作,要避免无限递归
                    if len(m_list) > 0 and \
                            (m_list[-1] in ('octal_binary', 'octal', 'binary')
                             or len(encode_str) < 8):
                        return False, raw_encode_str

                    # 将8进制直接转成16进制,也就是3个8进制数字转成2个16进制字符
                    # 先将每个8进制数字转成二进制,不足3个的前面补0
                    encode_str = encode_str.replace(' ', '').strip()
                    tmp_bin_list = ['%03d' % int(bin(int(t))[2:]) for t in list(encode_str)]
                    tmp_bin_list = [t for t in tmp_bin_list]
                    # logger.info(tmp_bin_list)
                    decode_str = ''.join(tmp_bin_list)
                else:
                    return False, raw_encode_str
            elif decode_method == 'decimal_ascii':
                if len(encode_str) < 4:
                    return False, raw_encode_str

                encode_str = encode_str.replace(' ', '').strip()
                rex = re.compile('^[0-9]+$', re.MULTILINE)
                if not self.regex_match(rex, encode_str):
                    return False, raw_encode_str

                # ascii 字符串,10进制最大127
                tmp_list = list(encode_str)
                ascii_list = []
                while len(tmp_list) > 0:
                    tmp_str = ''.join(tmp_list[:3])
                    if int(tmp_str) > 127:
                        tmp_str = ''.join(tmp_list[:2])
                        tmp_list = tmp_list[2:]
                    else:
                        tmp_list = tmp_list[3:]
                    ascii_list.append(chr(int(tmp_str)))
                decode_str = ''.join(ascii_list)
            elif decode_method in ['swap_case', 'reverse_alphabet', 'reverse']:
                # 如果这里不做限制,会无限递归下去
                if len(m_list) > 0:
                    for t in ['swap_case', 'reverse_alphabet', 'reverse']:
                        if t in m_list:
                            return False, raw_encode_str

                # 一定要包含 ascii 字符
                tmp_data = [t for t in encode_str if t in string.ascii_letters]
                if len(tmp_data) <= 0:
                    return False, raw_encode_str

                # rex = re.compile('^[A-Za-z0-9+/=]$', re.MULTILINE)
                # if not self.regex_match(rex, encode_str):
                #     return False, raw_encode_str

                if decode_method == 'swap_case':
                    new_data = []
                    for t in encode_str:
                        if t in string.ascii_lowercase:
                            t = t.upper()
                        elif t in string.ascii_uppercase:
                            t = t.lower()
                        new_data.append(t)
                    decode_str = ''.join(new_data)
                elif decode_method == 'reverse_alphabet':
                    # 字母逆序,a->z, z->a
                    new_data = []
                    for t in encode_str:
                        if t in string.ascii_letters:
                            if t in string.ascii_lowercase:
                                t = ord(t) + (25 - (ord(t) - ord('a')) * 2)
                                t = chr(t)
                            else:
                                t = ord(t) + (25 - (ord(t) - ord('A')) * 2)
                                t = chr(t)
                        new_data.append(t)
                    decode_str = ''.join(new_data)
                elif decode_method == 'reverse':
                    # 逆序
                    decode_str = encode_str[::-1]
                else:
                    return False, raw_encode_str
            elif decode_method == 'urlencode':
                if len(encode_str) < 4:
                    return False, raw_encode_str

                decode_str = unquote_plus(encode_str)
            elif decode_method == 'hex':
                if len(encode_str) < 4:
                    return False, raw_encode_str

                encode_str = encode_str.lower()
                rex = re.compile('^[a-f0-9]+$', re.MULTILINE)
                if self.regex_match(rex, encode_str.lower()):
                    # 修正基数位数的16进制数据
                    if len(encode_str) % 2 != 0:
                        encode_str += '0'

                    decode_str = force_text(hex2str(encode_str))
                else:
                    return False, raw_encode_str
            elif decode_method == 'zlib':
                if len(encode_str) < 4:
                    return False, raw_encode_str

                try:
                    decode_str = zlib.decompress(force_bytes(encode_str))
                    if self.calc_printable_percent(decode_str) < self.printable_percent:
                        return False, raw_encode_str

                except:
                    return False, raw_encode_str
            else:
                decode_str = encode_str.decode(decode_method)

            if len(decode_str) <= 0:
                return False, raw_encode_str
            elif force_bytes(encode_str) == force_bytes(decode_str):
                return False, raw_encode_str
            else:
                # 解码的内容只有可打印字符,才认为合法
                if self.only_printable:
                    printable_percent = 1.0
                else:
                    printable_percent = self.printable_percent

                is_printable = True
                # 如果可打印字符低于一定的百分比,就认为解码失败
                if self.calc_printable_percent(decode_str) < printable_percent:
                    is_printable = False

                if is_printable is False:
                    if self.last_result_printable is False:
                        return False, raw_encode_str

                self.last_result_printable = is_printable

                return True, decode_str
        except Exception as e:
            if self.verbose:
                logger.exception(e)
            return False, raw_encode_str