无意之间在贴吧看到图片文件夹,第一次了解到图片隐写相关的东西,遂想深入了解一下。链接
LSB
LSB全称为 least significant bit,即最低有效位隐写技术。
先以下面的这个思路来理解LSB隐写或者相关的隐写技术的基本思路:
1、图片在计算机中存储的方式
不管是以RGB还是YUV来表示图片,一张图片其实就是矩阵。只要保留下这个矩阵,就可以显示图片。
2、如何隐写?
何为隐写?
所谓的隐写是指通过人眼看不到的消息,人眼的对于颜色等属性的分辨率并不敏感,比如一个像素点为(128,128,128),另一个像素点为(128,129,128),128与129的差异就可以来存储信息。
因此可以通过有意识的修改图片的像素值,就可以实现信息的隐藏,肉眼难辨。
3、为何选择最低有效位?
我们即想传播信息,也要保证图片的不会被修改的太明显,那就只能从最低位入手,因为如果修改其他的位,对像素值修改较大,就不是“隐写”了。
4、具体的思路
—原数据处理:
不管是中文还是英文,图片等等最后都可以转换为二进制数据;
如果是图片,应该需要先对原图片进行图片压缩,缩小数据量;
—宿主图处理:
将处理后的原数据通过某个规则“隐写”到宿主图片中。
—获取原数据
对处理过的宿主图进行反向操作,获取出原数据。
5、代码实现
这里有一个简答的代码实现,原址:链接
from PIL import Image as im
import re
replace_reg = re.compile(r'[1|0]$')
#替换最后一位的数据,source是被替换数据,target是目标数据,就是batarget放到source最后一位
def repLstBit(source,target):
return replace_reg.sub(target,source)
#运行结果:'123X'
print(repLstBit("111110","1"))
#字符串转换二进制,不够八位的话补齐8位
def encode(s):
return ''.join(bin(ord(c)).replace('0b','').rjust(8,'0') for c in s)
#切割从图像中收集到的数据,就是把载密图像的对应最后一位提取出来之后需要进行切割
def cut_text(text,lenth):
textArr = re.findall('.{'+str(lenth)+'}',text)
tempStr = text[(len(textArr) * lenth):]
if len(tempStr)!=0:
textArr.append(text[(len(textArr)*lenth):])
return textArr
#二进制转换成字符串,看上面切割方法的注释即可理解该方法存在的意义
def decode(s):
bitArr = cut_text(s,8)
return "".join(chr(int(i,2)) for i in bitArr)
#读取宿主图像和要写入的信息生成载密图像。
if __name__ == '__main__':
img = im.open("D:/StegAnograpy/dove.png")
width = img.size[0]
height = img.size[1]
hideInfo = "Hello ImageSteg"
hideBitArr = encode(hideInfo)
count = 0
bitInfoLen = len(hideBitArr)
print(hideBitArr)
for i in range(width):
for j in range(height):
if count == bitInfoLen:
break;
pixel = img.getpixel((i,j));
print(pixel[0])
sourceBit = bin(pixel[0])[2:]
print(sourceBit)
rspBit = int(repLstBit(sourceBit,hideBitArr[count]),2)
count += 1
img.putpixel((i,j),(rspBit,rspBit,rspBit))
img.save("D:/StegAnograpy/dove1.png")
感触
隐写技术的应用前景是广阔的,特别是可以存储大量数据(g级)的隐写规则。
隐写不仅仅局限于图片,其实音频,视频,隐藏的东西可以更多。
图种
图种即一种采用特殊方式将图片文件与压缩文件结合起来的文件。该文件一般外观上为图片文件,可以正常预览图片;将该图片下载到本地后,可以通过修改文件的后缀名(如将.jpg改为.zip)并使用压缩软件对其解压缩,获取隐藏在图片文件中的压缩文件。虽然图种携带的是压缩包,包内可以是任意的文件,但文件增大,图种的大小也会随之增大。所以通常图种中夹带的压缩包很小(例如种子文件),故称为图种。
至于其原理:简单的说就是把图片与压缩文件用二进制的方式合并起来。图片的读取只需要读取前半部分的数据即可以正常显示,压缩文件只需要读取后半部分的数据即可以正常读取。
具体的本地制作操作步骤如下,来自百度百科:
copy文件合并
调出运行框:开始—-运行—CMD
在光标所在地方输入 copy /b E:2.jpg+E:1.rar E:output.jpg 然后回车。
然后:会出现:“E:2.jpg E:1.rar已复制 1 个文件。”
这样就完成了文件的合并。将jpg文件与rar文件合并起来了。合并后的文件在E盘,名字为output.jpg
我们把这个图片由.jpg改成.rar结尾以后可以发现仍然可以解压缩得到我们的文件,改成jpg依然是一张图片。