Skip to content
  • P
    Projects
  • G
    Groups
  • S
    Snippets
  • Help

xiaoqi / mp4giftconvert

  • This project
    • Loading...
  • Sign in
Go to a project
  • Project
  • Repository
  • Issues 0
  • Merge Requests 0
  • Pipelines
  • Wiki
  • Snippets
  • Members
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
  • Files
  • Commits
  • Branches
  • Tags
  • Contributors
  • Graph
  • Compare
  • Charts
Switch branch/tag
  • mp4giftconvert
  • obfusetablebase64.py
Find file
BlameHistoryPermalink
  • xiaoqi's avatar
    Update .gitignore and untrack ignored files · a65bde03
    xiaoqi committed 4 weeks ago
    a65bde03
obfusetablebase64.py 4.57 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
class ObfuseTableBase64:
    MAX_LENGTH = 5
    MAX_CODE_TIME = 3
    placeHolder = ord('l')  # 'l'的ASCII码

    # 初始化编码表和解码表
    @classmethod
    def __init__(cls):
        # 初始化临时数组 
        tmp0 = [ord(c) for c in '09_-18634275#']
        tmp1 = [0x41 + i for i in range(len(tmp0))]
        tmp2 = [tmp1[-1] + i + 1 for i in range(len(tmp1))]
        tmp3 = [0x61 + i for i in range(len(tmp1))]
        tmp4 = [tmp3[-1] + i + 1 for i in range(len(tmp3))]

        data2Arr = [
            tmp3,  # 0 
            tmp0,  # 1 
            tmp1,  # 2 
            tmp4,  # 3 
            tmp2  # 4
        ]

        # 生成65字符的中间表
        data65 = []
        for i in range(5 * len(tmp0)):
            quotient, remainder = divmod(i, 5)
            data65.append(data2Arr[remainder][quotient])

            # 生成64字符的编码表
        idx = data65.index(cls.placeHolder) if cls.placeHolder in data65 else 0
        cls.encodingTable = data65[:idx] + data65[idx + 1:] if idx < len(data65) else data65[:64]

        # 生成解码表
        cls.decodingTable = [-1] * 256
        for i, char in enumerate(cls.encodingTable):
            cls.decodingTable[char] = i

    @classmethod
    def encode(cls, data):
        if isinstance(data, str):
            data = data.encode('utf-8')

        modulus = len(data) % 3
        output_length = (len(data) // 3) * 4 + (4 if modulus else 0)
        encoded = bytearray(output_length)

        for i in range(0, len(data) - modulus, 3):
            byte1, byte2, byte3 = data[i], data[i + 1], data[i + 2]
            encoded[i // 3 * 4] = cls.encodingTable[(byte1 >> 2) & 0x3F]
            encoded[i // 3 * 4 + 1] = cls.encodingTable[((byte1 << 4) | (byte2 >> 4)) & 0x3F]
            encoded[i // 3 * 4 + 2] = cls.encodingTable[((byte2 << 2) | (byte3 >> 6)) & 0x3F]
            encoded[i // 3 * 4 + 3] = cls.encodingTable[byte3 & 0x3F]

        # 处理余数情况 
        if modulus == 1:
            byte = data[-1]
            encoded[-4] = cls.encodingTable[(byte >> 2) & 0x3F]
            encoded[-3] = cls.encodingTable[((byte << 4) & 0x3F)]
            encoded[-2:] = [cls.placeHolder] * 2
        elif modulus == 2:
            byte1, byte2 = data[-2], data[-1]
            encoded[-4] = cls.encodingTable[(byte1 >> 2) & 0x3F]
            encoded[-3] = cls.encodingTable[((byte1 << 4) | (byte2 >> 4)) & 0x3F]
            encoded[-2] = cls.encodingTable[((byte2 << 2) & 0x3F)]
            encoded[-1] = cls.placeHolder

        return encoded.decode('utf-8')

    @classmethod
    def decode(cls, data):
        if isinstance(data, str):
            data = data.encode('utf-8')

        data = cls.discard_non_base64_bytes(data)
        modulus = 0
        if data[-2] == cls.placeHolder:
            modulus = 1
        elif data[-1] == cls.placeHolder:
            modulus = 2

        output_length = ((len(data) // 4) - 1) * 3 + (4 - modulus)
        decoded = bytearray(output_length)

        for i in range(0, len(data) - 4, 4):
            b1 = cls.decodingTable[data[i]]
            b2 = cls.decodingTable[data[i + 1]]
            b3 = cls.decodingTable[data[i + 2]]
            b4 = cls.decodingTable[data[i + 3]]

            decoded[i // 4 * 3] = (b1 << 2) | (b2 >> 4)
            decoded[i // 4 * 3 + 1] = (b2 << 4) | (b3 >> 2)
            decoded[i // 4 * 3 + 2] = (b3 << 6) | b4

        # 处理末尾
        if modulus == 1:
            b1 = cls.decodingTable[data[-4]]
            b2 = cls.decodingTable[data[-3]]
            decoded[-1] = (b1 << 2) | (b2 >> 4)
        elif modulus == 2:
            b1 = cls.decodingTable[data[-4]]
            b2 = cls.decodingTable[data[-3]]
            b3 = cls.decodingTable[data[-2]]
            decoded[-2] = (b1 << 2) | (b2 >> 4)
            decoded[-1] = (b2 << 4) | (b3 >> 2)

        return decoded.decode('utf-8')

    @classmethod
    def discard_non_base64_bytes(cls, data):
        return bytearray([b for b in data if cls.is_valid_base64_byte(b)])

    @classmethod
    def is_valid_base64_byte(cls, byte):
        if byte == cls.placeHolder:
            return True
        if byte < 0 or byte >= 128:
            return False
        return cls.decodingTable[byte] != -1

    @classmethod
    def obfuse_base64(cls, decode_str):
        if not (decode_str.startswith('{{') and decode_str.endswith('}}')):
            if decode_str.startswith('"') and decode_str.endswith('"'):
                decode_str = decode_str[1:-1]
            try:
                decode_str = cls.decode(decode_str)
            except Exception as e:
                print(f"解码错误: {e}")
        return decode_str