from PIL import Image
input_pic=input("please input the path of the png image that need to be encrypted:")
input_text=input(("please input the path of the text that need to be hidden:"))
to_be_lsbed=Image.open(input_pic)
f=open(input_text,"r")
flag=f.read()
counter=0
flag_bin=""
for i in range(len(flag)):
binary=bin(ord(flag[i]))[2:]
flag_bin+="{:0>8}".format(binary)#注意要把二进制填充至8位,不然没法解密
width,height=to_be_lsbed.size
been_lsbed=Image.new("RGBA",(width,height))#注意有的图象是RGB,有的是RGBA,A=alpha,透明度
#遍历宽高
for y in range(height):
for x in range(width):
RGB=to_be_lsbed.getpixel((x,y))
r,g,b,a=RGB
#flag_bin还剩下三个位以上,下一次加密的时候R,G,B都会被LSB
if len(flag_bin)-(counter+1)>=3:
lsbed_bin_r=str(bin(r))[:-1]+str(flag_bin[counter])
lsbed_bin_g=str(bin(g))[:-1]+str(flag_bin[counter+1])
lsbed_bin_b=str(bin(b))[:-1]+str(flag_bin[counter+2])
RGB_tuple=int(lsbed_bin_r,2),int(lsbed_bin_g,2),int(lsbed_bin_b,2),a
#flag_bin还剩下两个位,下一次加密的时候R,G,都会被LSB
elif len(flag_bin)-(counter+1)>=2 and len(flag_bin)-(counter+1)<3:
lsbed_bin_r=str(bin(r))[:-1]+str(flag_bin[counter])
lsbed_bin_g=str(bin(g))[:-1]+str(flag_bin[counter+1])
RGB_tuple=int(lsbed_bin_r,2),int(lsbed_bin_g,2),b,a
#flag_bin还剩下一个位,下一次加密的时候只有R会被LSB
elif len(flag_bin)-(counter+1)>=1 and len(flag_bin)-(counter+1)<2:
lsbed_bin_r=str(bin(r))[:-1]+str(flag_bin[counter])
RGB_tuple=int(lsbed_bin_r,2),g,b,a
#一个位也没有了,加载原数据
elif len(flag_bin)-(counter+1)<1:
RGB_tuple=r,g,b,a
#逐个像素的画
been_lsbed.putpixel((x,y),RGB_tuple)
counter+=3
been_lsbed.save("out.png")
print("LSB encryption has been completed.")
虽然很粗糙,但是还是成功了!!!下图是用LSB解密工具Zsteg的解密结果: