base64编码原理
Base64 将8比特位为一个单元
的字节数据拆分为以6个比特位为一个单元
的二进制片段;每6个比特位单元
对应Base64索引表中的一个字符
;
比如:
经过base64编码的 Lucy 为 THVjeQ==,算法过程如下:
文本 | L u c y |
ASCII编码 | 76 117 99 121 |
8bit字节 | 01001100 001110101 01100011 01111001 00000000(补) 00000000(补) |
6bit字节 | 010011 000111 010101 100011 011110 010000 000000 000000 |
Base64索引值 | 19 7 21 35 30 16 (补位) (补位) |
Base64编码 | T H V j e Q = = |
由于Lucy只有4个字母,所以按3个一组的话,第二组还有两个空位。所以需要用00000000来补位,这里就需要注意,因为是需要补齐而出现的0,转化成十进制的时候就不能按常规用base64编码表来对应,所以不是A,编码后对应 “=”
base64解码脚本
通过以上的编码原理,写出以下自定义字典的解码脚本:
def custom_base64_decode(encoded_data, custom_dict):
if len(custom_dict) != 64:
raise ValueError("Custom dictionary must contain exactly 64 characters.")
# 创建反向映射字典
reverse_dict = {char: index for index, char in enumerate(custom_dict)}
# 移除填充字符'='
padding = len(encoded_data) % 4
encoded_data = encoded_data.rstrip('=')
# 将编码数据分割成4字符的块
blocks = [encoded_data[i:i+4] for i in range(0, len(encoded_data), 4)]
# 解码每个块
decoded_bytes = []
for block in blocks:
# 将每个字符映射回其6位索引值
indices = [reverse_dict[char] for char in block]
# 将这些6位值重新组合成3个8位的字节
for i in range(3):
if i < len(indices) - 1:
byte = (indices[i] << 2) | (indices[i+1] >> 4)
decoded_bytes.append(byte)
if i < len(indices) - 2:
byte = ((indices[i+1] & 0x0f) << 4) | (indices[i+2] >> 2)
decoded_bytes.append(byte)
if i < len(indices) - 3:
byte = ((indices[i+2] & 0x03) << 6) | indices[i+3]
decoded_bytes.append(byte)
# 根据原始数据的长度移除多余的字节(如果有的话)
original_length = len(encoded_data) // 4 * 3
if padding:
original_length -= padding - 1
decoded_bytes = decoded_bytes[:original_length]
# 将字节转换为字符串
decoded_data = bytes(decoded_bytes).decode('utf-8', errors='ignore')
return decoded_data
# 自定义字典
custom_dict = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
# 注意:这里的数据应该是使用上述自定义字典编码的数据
encoded_data = "THVjeQ=="
# 使用自定义字典进行解码
try:
decoded_data = custom_base64_decode(encoded_data, custom_dict)
print(f"解码后的字节串: {decoded_data}")
except ValueError as e:
print(e)
然后github上面有个base64编码和解码的脚本,如下:
poc1.py
def xdd_base64():
# ...(省略了之前的函数定义,因为它们已经在上面的代码中定义了)
"""
base64,编码和解码
:return:
"""
strbase64 = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
dictbase64 = {k:i for i,k in enumerate(strbase64)}
dictbase64[b"="[0]] = 0
def base64Encode(stt:str)->bytes:# 编码
"""
base64 编码,将字符串转成 base64格式的字符串
:param stt:
:return:
"""
bstt = stt.encode(encoding="utf-8")
# print(bstt,"====")
k = 0
count = len(bstt)
barr = bytearray()
for i in range(3,count,3): #3*8=4*6
units = bstt[k:i]
barr.extend(getBytearry(units))
k = i
else:
if k<count: #最后字节数不够3个字节。补0
num = k-count+3
endunits = bstt[k:] +b"\x00"*num #长度不够补0
barr.extend(getBytearry(endunits))
if num : barr[-num:] = b"=" * num #末尾补等号
# print(endunits)
return bytes(barr)
def getBytearry(nuits:bytes)->bytearray:
"""
将3个8位的字节,转成4个6位的字节
:param nuits:
:return:
"""
barr = []
barrint = int.from_bytes(nuits,'big')
for i in range(18,-1,-6):
# 注意0x3F是16精制数,对应二精制数是11 1111 对应10进制数是63,与6个1的二进制数做与运算,相当于支取最后6个二进制数
barr.append(strbase64[barrint>>i if i==18 else barrint>>i & 0x3F])
return barr
def base64Decode(stt:bytes)->bytes: #解码
strarr = (stt[i-4:i] for i in range(4,len(stt)+1,4))
arrby = bytearray()
num = 0
for nuits in strarr:
rint = 0
for k in nuits:
if k == b"="[0]: num +=1 #统计尾部等号个数
rint = (rint << 6) + dictbase64[k]
arrby.extend(rint.to_bytes(3,"big"))
while num: #去除尾部0字符
arrby.pop()
num -= 1
return bytes(arrby)
# 返回包含编码和解码方法的对象
return {
'encode': base64Encode,
'decode': base64Decode
}
# 创建Base64编解码器对象
base64_codec = xdd_base64()
# 解码函数
def decode_base64_string(encoded_string):
"""
解码Base64编码的字符串。
:param encoded_string: Base64编码的字符串
:return: 解码后的原始字符串
"""
# 将Base64编码的字符串转换为字节串
encoded_bytes = encoded_string.encode('ascii')
# 使用base64Decode函数解码字节串
decoded_bytes = base64_codec['decode'](encoded_bytes)
# 将解码后的字节串转换为字符串(假设是UTF-8编码)
decoded_string = decoded_bytes.decode('utf-8')
return decoded_string
# 示例用法
encoded_str = '1jfWHCyuH1HHZ0x9XS7MFw==' # Base64编码的"Hello world!"
decoded_str = decode_base64_string(encoded_str)
print(decoded_str) # 输出: Hello world!
poc2.py
import base64
import poc2
stt = ["编码和解码的字符串"]
for s in stt:
xddbase = poc2.xdd_base64()
destr = xddbase.encode(s)
sysb64 = base64.b64encode(s.encode())
print("base64编码:\t{}\t\t系統base64:\t{}".format(destr,sysb64))
enstr = xddbase.decode(destr)
print("base64解码:\t{}\t\t系統base64:\t{}".format(enstr,base64.b64decode(sysb64)))
print()