LSB图片隐写
介绍
LSB全称为 least significant bit,也就是最低有效位。LSB图片隐写是一种比较常见的信息隐藏方法。
图片中的像素一般是由RGB三原色(红绿蓝)组成,每一种颜色占用8位。而如果我们将每个数值加一或者减一,对图片的影响用眼睛几乎无法辨别出来。所以可以利用这个效果在最后一位放置想要存储的数据。当想要提取数据时只需要将每个像素点每个通道的最低值取出即可。
存储大小
对于一个有RGBA通道的图片,一个像素点占 8bit * 4 = 32bit 可以存储 4bit 的数据( 8 : 1 )。
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 def hide (file,img_file ): with open (file,'rb' ) as f: data = f.read() data_len = len (data) data = data_len.to_bytes(4 ,byteorder="big" ) + data data_len = len (data) img = cv.imread(img_file,1 ) height,width,channel = img.shape if channel != 4 : add_channel = np.ones((height,width,4 - channel),dtype=np.uint8) * 255 img = np.concatenate((img,add_channel),axis=2 ) byte_index = 0 bit_index = 7 for i in range (height): for j in range (width): for k in range (4 ): img[i][j][k] = ( img[i][j][k] & 0xFE ) | ((data[byte_index] >> bit_index) & 0x01 ) bit_index -= 1 if bit_index < 0 : bit_index = 7 byte_index += 1 if byte_index >= data_len: cv.imwrite("1.png" ,img) print ("OK" ) return print ("NO" )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 def show (img_file,file ): img = cv.imread(img_file,-1 ) data_len = 0 data_bit = 0 index = 0 byte = 0 height,width,channel = img.shape with open (file,'wb' ) as f: for i in range (height): for j in range (width): for k in range (4 ): if index < 32 : data_len <<= 1 data_len += img[i][j][k] & 0x01 data_bit = data_len * 8 index += 1 else : byte <<= 1 byte += 1 if img[i][j][k] & 0x01 == 1 else 0 index += 1 if index % 8 == 0 : f.write(byte.to_bytes(1 ,byteorder="big" )) byte = 0 if index > data_bit: print ("OK" ) return print ("NO" )
总结
LSB图片隐写这种方式比较容易实现,但是太容易被检测到,正常情况下图片最低位0和1出现的概率是比较接近的,经过这种方式隐写后就破坏了这种规则,这也就使隐藏的数据被发现了。(毕竟隐写的意义在于对数据的隐藏)