目录
Python实例题
题目
Python3图片隐写术
实现原理
将秘密信息编码到图片的像素中。由于人眼对颜色的细微变化不敏感,可以通过修改像素值的最低位(通常是最后 1-2 位)来存储秘密信息,而不会引起视觉上的明显变化。
代码实现
from PIL import Image
import argparse
import os
def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
"""将文本转换为二进制字符串"""
bits = bin(int.from_bytes(text.encode(encoding, errors), 'big'))[2:]
return bits.zfill(8 * ((len(bits) + 7) // 8))
def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
"""将二进制字符串转换为文本"""
n = int(bits, 2)
return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode(encoding, errors) or '\0'
def hide_message(image_path, message, output_path):
"""将消息隐藏到图片中"""
# 打开图片
img = Image.open(image_path).convert('RGB')
width, height = img.size
pixels = img.load()
# 将消息转换为二进制
binary_message = text_to_bits(message)
# 计算可容纳的最大位数
max_bits = width * height * 3 # 每个像素有RGB三个通道
# 检查消息是否太长
if len(binary_message) > max_bits:
raise ValueError(f"消息太长,无法隐藏在图片中。最大可隐藏 {max_bits} 位,而消息有 {len(binary_message)} 位。")
# 添加终止标记(8个零)
binary_message += '00000000'
# 隐藏消息
index = 0
for y in range(height):
for x in range(width):
r, g, b = pixels[x, y]
# 修改R通道的最低位
if index < len(binary_message):
r = (r & ~1) | int(binary_message[index])
index += 1
# 修改G通道的最低位
if index < len(binary_message):
g = (g & ~1) | int(binary_message[index])
index += 1
# 修改B通道的最低位
if index < len(binary_message):
b = (b & ~1) | int(binary_message[index])
index += 1
# 更新像素
pixels[x, y] = (r, g, b)
# 如果消息已经全部隐藏,则退出循环
if index >= len(binary_message):
break
else:
continue
break
# 保存结果
img.save(output_path)
print(f"消息已成功隐藏到图片中,保存至 {output_path}")
def extract_message(image_path):
"""从图片中提取隐藏的消息"""
# 打开图片
img = Image.open(image_path).convert('RGB')
width, height = img.size
pixels = img.load()
# 提取二进制消息
binary_message = ''
for y in range(height):
for x in range(width):
r, g, b = pixels[x, y]
# 提取R通道的最低位
binary_message += str(r & 1)
# 提取G通道的最低位
binary_message += str(g & 1)
# 提取B通道的最低位
binary_message += str(b & 1)
# 查找终止标记
end_index = binary_message.find('00000000')
if end_index == -1:
return "未找到隐藏的消息或消息已损坏"
# 提取消息部分
binary_message = binary_message[:end_index]
# 转换为文本
try:
message = text_from_bits(binary_message)
return message
except:
return "无法解码消息,可能图片未包含隐藏信息或已损坏"
def main():
parser = argparse.ArgumentParser(description='图片隐写术工具 - 隐藏或提取文本消息')
parser.add_argument('-m', '--mode', choices=['hide', 'extract'], required=True, help='模式:hide(隐藏) 或 extract(提取)')
parser.add_argument('-i', '--input', required=True, help='输入图片路径')
parser.add_argument('-o', '--output', help='输出图片路径(仅在隐藏模式下需要)')
parser.add_argument('-t', '--text', help='要隐藏的文本(仅在隐藏模式下需要)')
args = parser.parse_args()
if args.mode == 'hide':
if not args.output:
parser.error('隐藏模式需要指定输出图片路径 (-o)')
if not args.text:
parser.error('隐藏模式需要指定要隐藏的文本 (-t)')
hide_message(args.input, args.text, args.output)
else:
message = extract_message(args.input)
print("提取的消息:")
print(message)
if __name__ == "__main__":
main()
代码解释
-
文本与二进制转换:
text_to_bits
:将文本转换为二进制字符串text_from_bits
:将二进制字符串转换回文本
-
隐藏消息功能:
- 打开图片并转换为 RGB 模式
- 将消息转换为二进制,并添加终止标记(8 个零)
- 逐像素修改 RGB 通道的最低位,将二进制消息嵌入其中
- 保存修改后的图片
-
提取消息功能:
- 打开图片并转换为 RGB 模式
- 逐像素提取 RGB 通道的最低位,构建二进制字符串
- 查找终止标记,提取消息部分并转换为文本
使用方法
-
隐藏消息:
python steganography.py -m hide -i input.png -o output.png -t "这是一条秘密消息"
-
提取消息:
python steganography.py -m extract -i output.png
注意事项
- 此实现使用了最简单的 LSB 方法,容易被检测和破解
- 消息长度受限于图片大小,对于大消息需要更大的图片
- 建议使用无损压缩格式(如 PNG)保存结果,JPEG 等有损格式可能破坏隐藏的信息
- 图片隐写术可能涉及法律问题,请确保在合法合规的前提下使用