Python 中的图像隐写术

2025年3月17日 | 阅读 14 分钟

当今的计算世界围绕着“数据”一词运转。然而,数据为何如此引人入胜?在这个现代世界中,人们开始认识到数据对于扩大其业务范围的重要性。企业主利用数据来预测客户趋势、增加销售额并将组织推向新的高度。随着技术的飞速发展和数据的不断革新,保护数据已变得至关重要。数据共享也日益增加,每天都有成千上万条消息和数据在互联网上传输。数据保护是发送方的关键担忧,尤其重要的是,我们以一种只有接收方才能理解的秘密方法来加密消息。

在本教程中,我们将通过 Python 编程语言理解隐写术的概念及其实际应用。

理解隐写术的概念

隐写术是指一种将秘密消息隐藏在更大的消息中,以至于没有人能够知道隐藏消息的存在或内容的过程。隐写术的目的是在双方之间保持秘密通信。与加密术不同,加密术可以隐藏秘密消息的内容,而隐写术则隐藏了消息被传输的事实。尽管隐写术与加密术不同,但两者之间存在各种类比。一些作者将隐写术归类为一种加密术,因为隐藏的通信看起来像秘密消息。

理解使用隐写术而非加密术的优势

我们知道,加密术一直在保护发送方和预期接收方之间的机密性方面发挥着最终作用。然而,除了加密术之外,隐写术方法的使用也逐渐增加,为隐藏数据增加了更多的保护层。与单独使用加密术相比,使用隐写术的一个好处是,提出的秘密消息不会引起人们对其作为审查对象的关注。可见的加密消息,无论它们多么牢不可破,都会引起兴趣,并且在加密是非法的国家,它们本身可能是有罪的。

理解隐写术的类型

隐写术的工作已经在各种传输媒体上进行,并将其分为不同的类型

  1. 文本隐写术
  2. 图像隐写术
  3. 视频隐写术
  4. 音频隐写术
  5. 网络隐写术
  6. 电子邮件隐写术
Image Steganography using Python

现在,让我们来理解隐写术的基本模型

隐写术基本模型

Image Steganography using Python

正如我们在上图中所观察到的,实际文件(X)和需要隐藏的秘密消息(M)都作为输入馈送到隐写编码器。隐写编码器函数 f(X, M, K) 使用最小有效位编码等技术将秘密消息嵌入到封面图像文件中。生成的隐写图像看起来与封面图像文件非常相似,没有可见的变化。这就完成了编码。要检索秘密消息,隐写对象会被馈送到隐写解码器。

本教程将借助 Python 编程语言帮助我们实现图像隐写术。它将帮助我们编写 Python 脚本,使用一种称为最小有效位 (Least Significant Bit) 的技术来隐藏文本消息。

理解最小有效位隐写术

我们可以将数字图像描述为一组有限的数字值,称为像素。像素是图像中最小的单个元素,其值代表特定颜色在任何特定点的亮度。因此,我们可以将图像视为一个由像素组成的矩阵(或二维数组),其中包含固定数量的行和列。

LSB(或最小有效位)是一种方法,我们可以修改每个像素的最后一位,并用秘密消息的数据位替换它们。

Image Steganography using Python

从上图我们可以观察到,如果我们改变最高有效位(MSB),它会对最终值产生更大的影响;然而,如果我们改变最低有效位(LSB),对最终值的影响是微小的。因此,我们使用最低有效位(LSB)隐写术。

理解最小有效位技术的运作方式

每个像素包含三个值 - 红色、绿色、蓝色。这些值范围从 0 到 255,这意味着它们是 8 位值。让我们通过一个例子来理解这项技术的运作方式。假设我们要将消息“hi”隐藏到一个 4x4 的图像中,该图像的像素值如下所示

借助 ASCII 表,我们可以将秘密消息转换为十进制值,然后再转换为二进制形式:**0110100 0110101**。现在,我们可以逐一遍历像素值。一旦我们将它们转换为二进制,我们就可以按顺序用这些消息位替换每个最小有效位(例如,**225** 的二进制是 **11100001**,然后我们可以将最后一位,即最右边的位(1),替换为初始数据位(0),依此类推)。这将允许我们将像素值仅修改 +1 或 -1,这是完全无法察觉的。执行 LSBS 后的像素输出值如下:

使用 Python 将文本隐藏到图像中

以下部分主要侧重于借助 Python 脚本实现隐藏和显示过程的逐步方法。

此方法的步骤如下

**步骤 1:** 导入所有必需的 Python 库。

**步骤 2:** 定义一个将任何类型数据转换为二进制的函数,我们将在编码和解码阶段使用它将秘密数据和像素值转换为二进制。

**步骤 3:** 定义另一个函数,通过更改 LSB 来隐藏图像中的秘密消息。

**步骤 4:** 编写一个函数来从隐写图像中解码隐藏的消息。

**步骤 5:** 编写另一个函数,该函数接受用户输入的图像名称和秘密消息,并调用 **hide_data()** 函数来编码消息。

**步骤 6:** 定义一个函数,用于询问用户输入需要解码的图像名称,并调用 **show_data()** 函数以返回解码后的消息。

**步骤 7:** 定义主函数。

让我们看看以上步骤的实际应用

导入 Python 库

我们将从导入项目所需的库开始。如果系统中找不到任何使用的库,请使用 pip 安装程序进行安装。

让我们考虑以下 Python 脚本来理解这一点

示例

说明

在上一个代码片段中,我们导入了 **OpenCV** 库以及 **NumPy** 和 **types** 库。

类型转换为二进制

现在,我们将定义一个函数来将任何类型的数据转换为二进制。我们将在编码和解码阶段使用此方法将秘密数据和像素值转换为二进制。

让我们考虑以下 Python 脚本来理解这一点

示例

输出

说明

在上一个代码片段中,我们定义了一个名为 **msg_to_bin()** 的函数,它接受用户输入的 **msg** 参数(数据)。然后,我们使用 **if-elif-else** 条件语句来检查以消息和图像形式输入的秘密数据的类型,并将它们转换为二进制。

将秘密数据隐藏到图像中

一旦转换为二进制格式完成,我们将定义一个函数来通过更改最小有效位来隐藏图像中的秘密消息。

让我们考虑以下脚本来理解这一点

示例

说明

在上一个代码片段中,我们定义了一个接受图像文件和秘密消息两个参数的函数。然后,我们计算了用于编码的最大字节数,并检查要编码的字节数是否小于图像中的最大字节数。然后,我们将数据的索引设置为 0 并将秘密数据转换为二进制。然后,我们找到数据的长度,并使用 for 循环遍历图像中的像素值,将 RGB 值转换为二进制格式,并为每个像素隐藏数据。

从隐写图像中解码隐藏的消息

现在,我们将编写一个函数来从隐写图像中解码隐藏的消息。让我们考虑以下脚本来理解这一点

示例

说明

在上一个代码片段中,我们定义了 **show_data()** 函数,它接受图像文件。在此函数内,我们定义了空的二进制数据,并使用 for 循环遍历图像像素并将 RGB 像素转换为二进制格式。我们还提取了每个像素的数据,然后将其按 8 位分割并转换为字符。最后,我们检查分隔符并将其删除以显示实际隐藏的消息。

编码消息

我们现在将定义一个函数,该函数从用户那里接受图像名称和秘密消息。我们还将调用 **hide_data()** 函数来编码消息。

让我们考虑以下脚本来理解这一点

示例

说明

在上一个代码片段中,我们定义了一个名为 **encodeText()** 的函数来编码包含图像的秘密消息。在此函数内,我们使用 **input()** 函数要求用户输入图像文件名,并使用 **OpenCV** 库读取该文件。然后,我们打印图像的详细信息以及图像本身。然后,我们要求用户输入要编码的文本消息以及编码图像的新文件名。最后,我们调用 **hide_data()** 函数来将秘密消息隐藏到选定的图像中。

解码消息

现在,我们将定义一个函数来要求用户输入需要解码的图像文件的名称,并调用 **show_data()** 函数以返回解码的消息。

让我们考虑以下 Python 脚本来演示这一点

示例

说明

在上一个代码片段中,我们定义了另一个名为 **decodeText()** 的函数,它允许用户解码任何图像文件。在此函数内,我们要求用户输入需要解码的图像文件的名称,并使用 **OpenCV** 库的某个函数读取该文件。然后,我们调整图像大小并显示隐写图像。我们还通过调用 **show_data()** 函数从图像文件中提取秘密文本数据,并为用户返回文本。

主函数

我们将设置主函数来启动图像隐写术的操作。我们将包含一个菜单,供用户选择编码数据或解码数据,然后继续执行。

让我们考虑以下演示此过程的 Python 脚本

示例

# image ste

说明

在上一个代码片段中,我们将主函数定义为 **steganography()**。我们在该函数内创建了一个菜单,并要求用户以 **'int'** 数据类型输入。然后,我们使用 **if-elif-else** 条件语句根据用户输入执行函数。最后,我们调用此主函数来执行程序。

让我们看看完整的程序代码及其执行后的输出。

完整程序

文件:imgSteganography.py

数据编码输出

Image Steganography 
1. Encode the data 
2. Decode the data 
 Select the option: 1

Encoding...
Enter image name (with extension): my_image.jpg
The shape of the image is:  (1080, 1920, 3)
The original image is as shown below: 

Image Steganography using Python

Enter data to be encoded: python tutorial Enter the name of the new encoded image (with extension): testimage.jpg Maximum bytes to encode: 589693

数据解码输出

Image Steganography 
1. Encode the data 
2. Decode the data 
 Select the option: 2

Decoding...
Enter the name of the Steganographic image that has to be decoded (with extension): testimage.jpg
The Steganographic image is as follow: 

Image Steganography using Python

Decoded message is python tutorial