代码如下
import random
import string
import numpy as np
#5000bits的数据所占字节
bytes = 5000//8
#生成每次都不同的随机数据
def generate_random_letters(length):
letters = string.ascii_letters # 包含所有英文字母的字符串
random_letters = ''.join(random.choice(letters) for _ in range(length))
return random_letters
random_data = generate_random_letters(bytes)
end_str = "00000000"
#chr()函数将一个整数参数转换为对应的ASCII字符
end = chr(int(end_str,2))#\x00
with open('input_secret_text.txt','w') as f_raw:
#写入字符串
f_raw.write(random_data)
f_raw.close()
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
input_secret_text_path = "input_secret_text.txt"
output_secret_text_path = "output_secret_text.txt"
Lena_path = "C:/Users/86138/Desktop/Lena.bmp"
L_mod_path = "C:/Users/86138/Desktop/Lena_mod.bmp"
Airplane_path = "C:/Users/86138/Desktop/Airplane.bmp"
A_mod_path = "C:/Users/86138/Desktop/Airplane_mod.bmp"
Baboon_path = "C:/Users/86138/Desktop/Baboon.bmp"
B_mod_path = "C:/Users/86138/Desktop/Baboon_mod.bmp"
com_img_path = "D:/PyCharm/programm/usst/compare.png"
def read_image():
L_raw_image = Image.open(Lena_path)
return L_raw_image
def read_text():
f = open(input_secret_text_path,'r',encoding="utf-8")
text = f.read()
f.close()
return text
def insertText(secret_text,raw_image):
mod_image = raw_image.copy()
width = mod_image.size[0]#512
height = mod_image.size[1]#5
#将625个数据化为二进制数据
#从文档中读出加密信息并转换为二进制字符串
binstr = text_to_binary(secret_text)
#拼贴结束字段
#binstr为二进制字符串
binstr += end_str
#print(binstr)
i = 0
#遍历图像的每个像素
for w in range(width):
for h in range(height):
if i == len(binstr):
break
#获取当前像素值 灰度值:范围从0到255 使用一个字节存储灰度值,可以表示256个不同的灰度级别
pixel = mod_image.getpixel((w,h))
#print(value)
bit = int(binstr[i])
#lsb低位替换
modified_pixel = lsb_gray_pixel(pixel, bit)
mod_image.putpixel((w, h), modified_pixel)
i += 1
return mod_image
def lsb_gray_pixel(pixel, bit):
mask = 0xFE # 掩码,将最低有效位清零
#0xFE:11111110
#通过 pixel & mask 对 pixel 和 mask 进行按位与操作,将 pixel 的最低位清零。这样可以确保最低位保持为零。
pixel = (pixel & mask) | bit # 替换最低有效位
#|(按位或)操作符将清零后的 pixel 和给定的 bit 进行按位或运算。这样可以将 bit 的值替换为清零后的 pixel 的最低位。
return pixel
def text_to_binary(text):
binary_str = ''.join(format(ord(char), '08b') for char in text)
return binary_str
def getText(mod_img):
width = mod_img.size[0]#图像宽度 512
height = mod_img.size[1]#图像高度 512
get_text = ""
text = ""
countEND = 0
#遍历每个像素点
for w in range(width):
for h in range(height):
pixel = mod_img.getpixel((w,h))
get_text += get_lsb(pixel)
if len(get_text) == 8 :
# 转换成ASCII码
# 例:"0110 0001" -> 97 -> 'a'
ch = chr(int(get_text, 2))
if ch == end :
countEND = countEND + 1
if countEND == 2 :
break
text += ch
get_text = ""
return text
def get_lsb(value):
return format(value, '08b')[-1]
def write_text_to_file(text, output_secret_text_path):
with open(output_secret_text_path, 'w', encoding='utf-8') as f:
f.write(text)
f.close()
def main():
text = read_text()
raw_img = read_image()
mod_img = insertText(text,raw_img)
mod_img.save(L_mod_path)
secret = getText(mod_img)
#print(secret)
#print(text)
write_text_to_file(secret,output_secret_text_path)
#构造对比图
plt.rcParams['font.sans-serif']=['SimHei'] # 中文字体设置
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(131)
plt.title("嵌有秘密信息的载体图像")
plt.imshow(mod_img,cmap='gray')
plt.subplot(132)
plt.title("原始载体图像")
plt.imshow(raw_img,cmap='gray')
# 保存对比图
plt.savefig(com_img_path)
# 显示对比图
plt.show()
print(len(secret))
main()
当输入数据量为5000bits时提取出的数据存在乱码,随数据量的增大乱码减少至消失
请问产生原因及解决方法