LSB图像隐写

  1. 1. LSB图片隐写
    1. 1.0.1. 介绍
    2. 1.0.2. 存储大小
    3. 1.0.3. 实现
    4. 1.0.4. 总结

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出现的概率是比较接近的,经过这种方式隐写后就破坏了这种规则,这也就使隐藏的数据被发现了。(毕竟隐写的意义在于对数据的隐藏)