学习base64算法并尝试用python复现

好,第一篇学习记录,随便写点吧(希望不是最后一篇)

加/解密方法

加密范围为acsll码表内的字符,加密后的文本由码表中的字符组成

这个是默认码表'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',每个字符的索引即为编号

加密过程:

1.将字符按照acsll码转化为8位2进制数字

2.将2二进制数以6个为一组依次分组

3.将每组6位二进制数按照码表的索引转化为码表中的字符

4.若出现2或4个二进制数不够组为一组6位二进制数,就在后面添0补上,每补2个0在加密后的文本结尾添加一个'='

以上图为例子,加密'bs',bs按照ascll码分别转化为01100010,01110011,差两位数成为6的倍数,所以在末尾补上两个0。再将二进制数以6个为一组分位011000,100111,001100,按照码表分别转化为YnM,因为补过了两个0,所以在加密后的文本中需添加一个=。所以加密后的文本为YnM=

↓↓↓为python代码实现,支持码表替换功能

#base64解密,可选码表替换,new_code_tabke为替换的码表,默认不输入即为不替换码表
def base64encode(str1,new_code_tabke=None):
    #原码表备份code_table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    code_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    if  new_code_tabke:
        code_table=new_code_tabke
    # 遍历要加密的字符串进行第一次码表转化
    bin_str = ''
    for i in str1:
        bin_1=bin(ord(i))
        bin_str+='0'*(8-len(bin_1[2:]))+bin_1[2:]      #去掉bin()中的b
    # 计算结尾=的数量并补齐bin_str至6的倍数
    cout=0
    if len(bin_str)%6==4:
        cout=1
        bin_str=bin_str+'00'
    elif len(bin_str)%6==2:
        cout=2
        bin_str = bin_str + '0000'
    #以6个为一组对bin_str分组
    list_str=[]
    for i in range(0,len(bin_str),6):
        list_str.append(bin_str[i:i+6])
    #将list_str按照码表进行编译并补上=
    output_str=''
    for i in list_str:
        position=int(i,2)
        output_str+=code_table[position]
    output_str+='='*cout
    return output_str

# base64解密,可选码表替换,默认不替换
def base64decode(str1,new_code_tabke=None):
    # 原码表备份code_table='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    code_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    # 码表替换
    if new_code_tabke:
        code_table=new_code_tabke
    #去掉结尾的=,后续可忽略=加上的0所以不用特意将0删去
    cout=0
    while 1:
        if '=' in str1:
            str1=str1[:-1]
        else:
            break
    #按照码表反编译为6位二进制
    bin_6str = ''
    for i in str1:
        postion=code_table.find(i)
        bin_i=bin(postion)[2:]
        bin_6str+='0'*(6-len(bin_i))+bin_i
    #6位转8位并用acsll码转义,多出的可以自动忽略,也就是自动去=
    out_str=''
    for i in range(0,len(bin_6str)//8*8,8):
        out_str+=chr(int(bin_6str[i:i+8],2))
    return out_str

#测试用
if __name__ == "__main__":
    a='bs'
    x=base64encode(a)
    print(x)
    y=base64decode(x)
    print(y)

yysy,不太喜欢这个python代码标色

优点:省去了base64库的bytes_to_long()和long_to_bytes()的操作,简单方便,码表替换方便

缺点:如上省去了操作会导致碰到不可输出字符时无法正常输出结果

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注