好,第一篇学习记录,随便写点吧(希望不是最后一篇)
加/解密方法
加密范围为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()的操作,简单方便,码表替换方便
缺点:如上省去了操作会导致碰到不可输出字符时无法正常输出结果