图片隐写术,Python代码篇!图片中藏图片的思路!
图片隐写术已经发过两篇文章,分使用命令行和网页实现。但是并没有从代码层面来进行介绍。如果你是一个有追求的程序员,那么不写个代码,总是感觉缺点少么。至少我是这样的…. 还有人问我,能否实现图片中隐藏图片,这种需求当然需要自己来写代码了。具体思路见文末!
今天就说一说如何用Python来实现这个效果。其实,steghide也提供了源代码,但是是C的项目,我对他的项目构成不太了解,十多年前常用的C语言也基本还给老师了,所以还是写个Python的吧。从受众的角度来说,可能也是用python更友好。
今天的代码其实也非常简单,满打满算6行代码,核心代码才两行。主要是用到一个叫stegano的包。因为这是代码篇,命令行,路径,python语法,这些太基础我就不说了。
闲话说完,直接开干。
第一步:创建虚拟环境
创建一个conda虚拟环境
conda create -n stegano python =3.6 activate stegano
第二步:安装依赖包
pip install stegano
第三步:写代码(拷贝)
创建一个stegano.py文件。使用Ctrl+C Ctrl+V大法,三秒钟搞定。
#引入包 from stegano import lsb #定义加密文本 txt='''Tony''' # 用LSB算法将文字写入图片。 secret=lsb.hide('1.png',txt) #保存图片 secret.save('encoded_image.png') #读取图片并提取文字信息 txt=lsb.reveal('encoded_image.png') #打印文字信息 print(txt)
第四步:运行
输入命令:
python stegano.py
运行结束后,会生成一张加密后的图片,同时会显示文本信息。
如果没啥意外,这一圈搞下来应该很顺利。恭喜你有了自己的隐写术。你可以在这个基础上进行扩展,自定义,做成独立的软件等等。
中文乱码的问题
以上代码基本功能都已经实现了,但是如果你把tony换成中文,比如“托尼” ,那么你将会面临一个问题–乱码(羡慕英语国人,128个ASCII码走遍天下,永无乱码)。
多年以前,各种框架编码还不统一,乱码是一个令人头痛的问题。现在基本用UTF编码,很少出问题。这次突然又遇到老问题,有点蒙。极具迷惑性的是他源码里还特意写了UTF-8编码。为了理清思路,我把所有代码逻辑捋了一遍,最后绕一圈才发现,原来他提供了一个UTF-32LE的参数。
扩展内容
虽然分析代码费了一些时间,但是也有不少收获。功能很简单的一个小项目,细节到是不少,涉及到好多基础知识点。
比如
汉字如何转成二进制?
ASCII码和UNICODE编码是什么,他们是什么关系 ?
UTF-8,UTF-16,UTF-32的差别是什么?
如何读取每一个像素点上的RGB值?
以什么样的形式和格式保存读取文字信息?
如何判断文字信息最大值?
这种小项目很适合作为学习Python的一个例子。
不过,我估计关注具体逻辑的应该不多,就不在这里长篇大论了。
我可能会在博客里单独写一篇,作为自己的一个笔记。
关于图片中隐藏图片。
这里其实就是一个思路的问题。图片其实可以转换成Base64的字符串。一张图片就等于一串很长的字符串。还原的时候获取到Base64字符串,然后将字符串转换成图片就可以了。
经过我的计算和实践,完全可行,而且能藏的内容远超预期。
一张1920×1080的图片总共能隐藏(1920*1080*3)/8 个字节,约759KB。
上图是1437*1437的分辨率。转换成base64字符串大概是500507个字符,用UTF-8编码的英文字符只占用一个字节,所以这个图片的字符大概是488KB。
所以一张1080p的图片完全能藏得下这个图片。