LSB (Least Significant Bit) Principle and Code Implementation of Image Steganography

1. What is steganography?

Steganography is a technique and science about information hiding. The so-called information hiding refers to not letting anyone except the intended recipient know the transmission event or the content of the information. The English name of steganography is Steganography, which comes from Steganographia, a book about cryptography and steganography written by Trithemius. The title of the book comes from Greek, meaning "secret writing".

2. What is image steganography?

Image steganography is a technique that embeds secret information into an image medium without compromising the quality of its carrier. The third party neither perceives the existence of the secret information nor knows the existence of the secret information. Therefore, keys, digital signatures and private information can be safely transmitted in an open environment (such as the Internet or intranet). Simply sum it up 信息明明就在眼前,但是你却视而不见.

3. The principle of LSB steganography

In the storage of png images, each color representation requires 8 bits, that is, there are 256 colors, and a total of 256 cubic colors are included, that is, 16,777,216 colors. Human eyes can distinguish about 10 million different colors, and the remaining There are 6,777,216 indistinguishable colors.
insert image description here
So what is LSB? The color of each pixel can be represented by a decimal value of 0~255. Then the RGB (218, 150, 149) in the above figure is expressed in binary as: LSB steganography is to modify the lowest binary bit of the RGB color component
insert image description here
. The least significant bit (LSB), and human eyes will not notice the change before and after this, we only modify the lowest bit in RGB, such as modifying the last bit of the current pixel to 1, 1, 0. Then the above RGB Become 218->219:
insert image description here
The above changes are difficult to detect with the naked eye, and each pixel carries a bit of information, then we can use the lowest bit of eight bytes to store a bit of information, and this bit of information can be Convert it into ASCII characters, so as to achieve the purpose of steganographic information.

4. How to implement LSB steganography?

import numpy as np
import PIL.Image as Image

# 读取图片的像素信息
picture = Image.open('./pic/pic.jpg')
pic_data = np.array(picture)

# 读取要隐写的文件,长度为4893
with open('./pic/secret.py', encoding="utf-8") as file:
    secrets = file.read()

# 将图片拷贝一份,作为最终的图片数据
im_data = np.array(picture.copy()).ravel().tolist()

def cover_lsb(bin_index, data):
    '''
    :param bin_index:  当前字符的ascii的二进制
    :param data: 取出数组像素的八个数值
    :return: LSB隐写后的字符
    '''
    res = []
    for i in range(8):
        data_i_bin = bin(data[i])[2:].zfill(8)
        if bin_index[i] == '0':
            data_i_bin = data_i_bin[0:7] + '0'
        elif bin_index[i] == '1':
            data_i_bin = data_i_bin[0:7] + '1'
        res.append(int(data_i_bin, 2))
    return res


pic_idx = 0
# 采用LSB隐写技术,横向取数据,每次取9个数据,改变8个像素最低位
res_data = []
for i in range(len(secrets)):
    # 拿到隐写文件的字符ascii数值, 并转换为二进制,填充成八位
    index = ord(secrets[i])
    bin_index = bin(index)[2:].zfill(8)
    # 对数据进行LSB隐写,替换操作
    res = cover_lsb(bin_index, im_data[pic_idx * 8: (pic_idx + 1) * 8])
    pic_idx += 1
    res_data += res
# 对剩余未填充的数据进行补充填充,防止图像无法恢复
res_data += im_data[pic_idx * 8:]

# 将新生成的文件进行格式转换并保存,此处一定保存为压缩的png文件
new_im_data = np.array(res_data).astype(np.uint8).reshape((pic_data.shape))
res_im = Image.fromarray(new_im_data)
res_im.save('./pic/res_encode.png')

5. How to achieve steganographic data restoration?

import numpy as np
import PIL.Image as Image

# 打开隐写文件
picture = Image.open('./pic/res_encode.png')
pic_datas = np.array(picture).ravel().tolist()

# 字符的长度为4893
with open('./pic/secret.py', encoding="utf-8") as file:
    secrets = file.read()

str_len = len(secrets)
print('字符的长度为:', str_len)

# 将图片拷贝一份,作为最终的图片数据
im_data = np.array(picture.copy()).ravel().tolist()


def lsb_decode(data):
    '''
    :param bin_index:  当前字符的ascii的二进制
    :param data: 取出数组像素的八个数值
    :return: LSB隐写后的字符
    '''
    str = ''
    for i in range(len(data)):
        print(bin(data[i])[2:])
        data_i_bin = bin(data[i])[2:][-1]
        str += data_i_bin
    return str


pic_idx = 0
# 采用LSB隐写技术,横向取数据,每次取9个数据,改变8个像素最低位
res_data = []

for i in range(len(secrets)):
    # 拿到第i个数据,转换成二进制
    data = im_data[i * 8: (i + 1) * 8]
    data_int = lsb_decode(data)
    # 找到最低位
    res_data.append(int(data_int, 2))

# 将二进制数据转换成ASCII
str_data = ''
for i in res_data:
    temp = chr(i)
    str_data += temp
print(str_data)

6. Summary

The basic LSB principle is very simple and the easiest to implement, but its robustness is not good. Subsequent better hidden information will be realized through digital watermarking technology, and the article will be updated later.

Guess you like

Origin blog.csdn.net/l8947943/article/details/127088875