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]] = 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()

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值