Base64解码
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]] = 0def base64Encode(stt:str)->bytes:# 编码"""base64 编码,将字符串转成 base64格式的字符串:param stt::return:"""bstt = stt.encode(encoding="utf-8")# print(bstt,"====")k = 0count = len(bstt)barr = bytearray()for i in range(3,count,3): #3*8=4*6units = bstt[k:i]barr.extend(getBytearry(units))k = ielse:if k<count: #最后字节数不够3个字节。补0num = k-count+3endunits = bstt[k:] +b"\x00"*num #长度不够补0barr.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 barrdef base64Decode(stt:bytes)->bytes: #解码strarr = (stt[i-4:i] for i in range(4,len(stt)+1,4))arrby = bytearray()num = 0for nuits in strarr:rint = 0for 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 -= 1return 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 poc2stt = ["编码和解码的字符串"]
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()