【python实现base64算法】

python实现base64算法

base64编码

  1. 将给定的字符串转换成字节数组,进行步长为3的分割,每3个字节为一组,最后一组不够三个字节的,补0,如果最后一组是一个字节,剩下的两个字节补0;如果最后一组是两个字节,剩下的一个字节补0。

  2. 每6位组成一个新的字节,高位补00,构成一个新的二进制序列,最后根据base64索引表中的值找到对应的字符。

  3. 在第一步骤中,补了几个字节的0,就补几个=。

  4. 如将“abcd”经base64转码后得“YWJjZA==”。

def base_64(src:str):   # str='abcd'
    alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    ret = bytearray()
    if isinstance(src,str):
        src_code = src.encode()    # 进行编码
    else:
        return
    for offset in range(0,len(src_code),3):
        temp = src_code[offset:offset+3]  # b'abc'、b'd'
        r = 3 - len(temp)  # r:0,2
        if r:  # 如果r不为0,表示这是最后一组,
            temp += b'\x00'* r   # \x00表示两个十六进制真正的0(非字符0)
        # 进行移位运算
        x = int.from_bytes(temp,'big')  # 大端模式,从左向右 
        # 01100001 01100010 01100011 (abc)---- 01100100 00000000 00000000 (d)
        for i in range(18,-1,-6):
            index = x >> i if i == 18 else x >> i & 0x3F   # 0x3F表示16进制,是11 1111
            ret.append(alphabet[index])
    if r:  # 补了几个字节的0,就添加几个=
        ret[-r:] = b'='* r
    return bytes(ret)

res= base_64('abcd')    
print(res)  # b'YWJjZA=='

base64解码

import re
def decoded_base64(src:bytes):
    alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    pat_end = re.compile(b'[A-Za-z\d+/]{2,4}={0,2}')
    pat_not_end = re.compile(b'[A-Za-z\d+/]{4}')
    # 分块
    step = 4
    result = bytearray()
    for offset in range(0,len(src),step):
        end = offset+step
        block = src[offset:end]
        # 进行格式检查,分两种情况,结尾和不是结尾
        end_flag = True if end == len(src) else False
        length = len(re.match(pat_end,block).group(0)) if True else len(re.match(pat_not_end,block).group(0))
        if length != 4:
            print('不符合要求的输入')
            return
        # 符合字符串传入要求
        #对每一个block进行解码
        ret = 0
        for i,item in enumerate(block):
            # 分两种情况,结尾,不是结尾
            index = alphabet.find(item)   # 需要考虑index = -1,也就是item = '='的情况
            if index == -1:
                continue
            if b'=' in block:
                if block.find(b'=') == 2:
                    if i == 0:
                        ret += index << 2
                    if i == 1:
                        ret += index >> 4
                elif block.find(b'=') == 3:
                    if i == 0:
                        ret += index << 10
                    if i == 1:
                        ret += index << 4
                    if i == 2:
                        ret += index >> 2
            else:
                ret += index << (step - 1- i) * 6
        if block.find(b'=') == 2:
            ret1 = ret.to_bytes(1, 'big')
        elif block.find(b'=') == 3:
            ret1 = ret.to_bytes(2, 'big')
        else:
            ret1 = ret.to_bytes(3, 'big')  # 表示要转换成3个字节,大端模式
        result.extend(ret1)
    return bytes(result)
print(decoded_base64(b'YWJjZA=='))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值