隐写原理
直接上图便于理解:
Lucy经过Base64编码后的值为THVjeQ==
同时可以看到在编码过程中补了4个0。其实可以通过后面的等号来判断有没有填充0。一个等号相当于填充了两个0。在解码过程中等号直接被丢弃,同时通过等号的个数去除填充的0从而解码。
由于填充的0在解码时会被丢弃,那么就意味着这些填充的0,其实可以不按规则都填充0,可以是0,1的任意组合,对解码不产生影响。
正常情况编码为THVjeQ==:
隐写情况编码为THVjeV==:
总结来说就是隐藏的信息夹在在这些填充位上。因此我们需要将这些隐藏的信息提取出来。
信息提取
由上面的内容可知,隐藏的信息被夹在填充位上,而我们又可以通过"="来判断哪些字符串在编码过程中有填充,而填充的位数又等于"="的2倍。将所有夹在的信息汇总为二进制串在解码为对应的Ascii码值就可以得到隐藏的信息了。
代码如下:
import string
base64chars=string.ascii_uppercase+string.ascii_lowercase+string.digits+"+/"
bins=""
def getSecret(s):
global bins
six_bin=""
countZero=0
for item in s:
if item=="=":
countZero+=1
else:
six_bin += bin(int(base64chars.index(item)))[2:].zfill(6)
bins+=six_bin[-(countZero*2):]
with open("flag.txt","r") as f:
lines=f.readlines()
for line in lines:
line=line.strip()
if line.count("="):
getSecret(line)
s=""
for i in range(0,len(bins),8):
s+=chr(int(bins[i:i+8],2))
print(s)
运行结果
题目:
题目
总结
运行结果后面的信息其实是由于编码时填充的0所导致的,不影响我们知道结果。但是对于整体来说不能以填充时全0就代表没有隐藏信息,因为它所隐藏的其实是二进制串。