base64隐写解密代码以及介绍

502 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Base64由来

Base64 是一种编码方式,最早出现在电子邮件传输协议中。
电子邮件问世之初,传递消息时只支持 ASCII 字符,后来随着电子邮件的广泛使用,传递非ASCII字符内容的需求增加,例如:传输中文、传输文件(图片、视频)。
为解决这一问题,最好的方案是在不改变传输协议的基础上,做一种扩展方案来支持非ASCII内容传输把非 ASCII 字符用ASCII来表示,Base64编码应运而生。

Base64由来

二、Base64定义

Base64 是一种基于64个 ASCII 字符来表示二进制数据的表示方法
Base64 将8比特位为一个单元的字节数据拆分为以6个比特位为一个单元的二进制片段,每6个比特位单元对应Base64索引表中的一个字符,这样最终构成一个超过编码前字节数据33%的字符串。

Base64 中64个可打印字符包括字母A-Za-z、数字0-9,此外还有两个字符为+和/,这样构成了共有64字符的Base64索引表

Base64索引表

三、Base64编码原理

Base64 将8比特位为一个单元的字节数据拆分为以6个比特位为一个单元的二进制片段;每6个比特位单元对应Base64索引表中的一个字符
按照以上方式可以算出base64编码后的字符串大约比编码前增加了33%

为什么一些Base64后的字符中末尾有“==”

以上举例中:
编码前字节数正好被3整除,转化为二进制ASCII 编码( 3*8=24 )后,正好可以被6整除
编码前字节数不能被3整除,最后会余出1个或2个字节,那么编码时需要:

  • 使用 000000 字节值在末尾补足,使其字节数能够被3整除;
  • 编码时补位的6个比特位单元用 = 表示。

base64隐写解密

'''
base64隐写解密
'''

base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

flag=''
with open('en.txt','r') as f:
    for line in f.readlines():
        line=line[:-1]
        num=line.count('=')
        if num == 0 :
            continue
        lastchar = line[-(num+1)]
        
        #print(line,num,lastchar)
        myindex = base64chars.index(lastchar)
        #print(myindex)
        bin_str = bin(myindex)[2:].zfill(6)
        #print(bin_str)
        flag+=bin_str[6-2*num:]
        #print(bin_str[6-2*num:])
print(''.join([chr(int(flag[i:i + 8], 2)) for i in range(0, len(flag), 8)]))
        
        
        
        
            
        

base64隐写加密

'''
base64隐写加密

'''
import base64
flag = 'flag{1_am_fl0g}'
bin_str = ''.join([bin(ord(c)).replace('0b','').zfill(8) for c in flag])
#print(bin_str)
base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

with open('Plaintext.txt','r') as f0 , open('en.txt','w') as f1:
    for line in f0.readline():
        line = line.replace('\n','')
        #base64加密
        b64_str = str(base64.b64encode(line.encode('utf-8')))[2:-1]
        #print(b64_str)
        #num是0的个数
        num = b64_str.count('=')
        if num == 0:
            continue
        #隐写的地方,也就是需要改变的字符串
        lastchar = b64_str[-(num+1)]
        #其原来的索引
        myindex = base64chars.index(lastchar)
        bin_tmp = bin(myindex)[2:].zfill(6)
        #更新填充索引
        en_str = bin_tmp[:6-2*num]+bin_str[:num*2]
        #更新flag
        bin_str=bin_str[num*2:]
        #更新字符
        ch = base64chars[int(en_str,2)]
        #更新base64
        b64_str=b64_str[:-(num+1)]+ch+b64_str[-(num):]
        #写入
        f1.write(b64_str+'\n')