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