LSB信息隐藏——Python实现(完整解析版)

系列文章目录

仿射密码实验-Python实现
仿射密码实验——Python实现(完整解析版)
DES密码实验-C语言实现
MD5密码实验——Python实现(完整解析版)


文章目录

  • 系列文章目录
  • 前言
  • 实验方法
  • 实验环境
  • 实验内容
  • 实验步骤
    • 1.LSB原理
    • 2.确定设计模块
      • Lsb——embded
      • Lsb——extract
  • 实验结果
  • 实验心得
  • 完整代码


前言

1)了解图像平面位
2)掌握LSB信息隐藏的实现


实验方法

根据给出的LSB算法的描述,用所熟悉的语言,完成实验内容并简要描述实验操作步骤。

实验环境

计算机语言:Python
开发环境:Pycharm

实验内容

根据LSB算法完成LSB信息隐藏的实现。包括:信息嵌入、信息取出。

实验步骤

1.LSB原理

每个像素点的颜色RGB可以用十进制0~255的数值表示。LSB隐写就是修改RGB颜色分量的最低二进制位也就是最低有效位(LSB),而且每一个像素位点携带了一位信息,那么就可以利用八个字节的最低位存储一个比特信息,而该比特信息则可以转化为ASCII字符,从而达到隐写信息的目的。

2.确定设计模块

1.lsb_embed
2.lsb_extract
3.main函数(主程序)

项目架构:

Pic:存放图片
Txt:存放待嵌入信息和提取后信息
LSB-main:运行程序文件
在这里插入图片描述

Lsb——embded

1.用PIL库的Image读取图片像素信息
2.利用numpy库将读取的像素信息处理为矩阵
在这里插入图片描述

3.输入路径,读取待隐写的文件,将之前读取的图片一并拷贝
在这里插入图片描述

4.对每位字符进行ASCII处理,取到的二进制数由6位填充至8位
自定义函数cover_lsb进行lsb隐写操作
对于最低有效位LSB,用if判断进行替换选择二进制为0还是1
在这里插入图片描述
5.剩余未填充位进行补充填位,使得图像能够恢复
6.再使用处理后的新矩阵来生成嵌入图片

Lsb——extract

1.用PIL库的Image读取图片像素信息
2.利用numpy库将读取的像素信息处理为矩阵
在这里插入图片描述

3.提取过程中寻找最低位
在这里插入图片描述

4.用到lsb_decode来找寻最低位并返回
在这里插入图片描述

5.得到的数据进行二进制转ASCII的操作

实验结果

开启程序
在这里插入图片描述

1.隐写

在这里插入图片描述

进行人眼观察,嵌入信息后的图片与原图看不出明显差别
在这里插入图片描述

2.提取

在这里插入图片描述
在这里插入图片描述

提取的信息与原信息进行比对后,确认提取信息成功。
在这里插入图片描述

实验心得

本次实验做了关于LSB信息隐藏的实现,接触到了LSB作为一种隐写术的优缺点,比如它的原理十分简单,可以通过一些脚本快速实现嵌入信息,且嵌入后的图片psnr值得到保证的情况下就不容易被人眼看出,实现数据隐写;但同时它的鲁棒性不佳,相对于数字水印,容易通过工具如stegsolve进行分析得出或者脚本程序进行信息提取。
对于本次实验的代码,在提取部分是通过原始信息的长度来确定遍历的次数,在实际过程中一般是不知道提取信息的长度,这时候就需要尽量将遍历长度设置大一些,这样就算超过原始信息长度也可以通过无意义字符进行排除,从而获取最后的有效信息。

完整代码

# -*- coding: utf-8 -*-
# @Time    : 2022/10/17 14:38
# @Author  : 4v1d
# @File    : LSB-main.py
# @Software: PyCharm
import numpy as np
import PIL.Image as Imagedef lsb_embed(pic_src,file_src):# 读取图片的像素信息picture = Image.open('{}'.format(pic_src))pic_data = np.array(picture)# 读取要隐写的文件with open('{}'.format(file_src), 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 respic_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 += 1res_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')print("在pic中已生成res_encode.png")def lsb_extract(pic_src,file_src):# 打开隐写文件picture = Image.open('{}'.format(pic_src))pic_datas = np.array(picture).ravel().tolist()with open('{}'.format(file_src), 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_binreturn strpic_idx = 0# 采用LSB隐写技术,横向取数据,每次取9个数据,改变8个像素最低位res_data = []for i in range(str_len):# 拿到第i个数据,转换成二进制data = im_data[i * 8: (i + 1) * 8]data_int = lsb_decode(data)# 找到最低位res_data.append(int(data_int, 2))# 将二进制数据转换成ASCIIstr_data = ''for i in res_data:temp = chr(i)str_data += tempprint("提取成功,输出下列解密结果")print(str_data)with open('./txt/secret_out.txt', 'w',encoding="utf-8") as file:file.write(str_data)print('已保存在txt/secret_out.txt中')if __name__ == '__main__':title = """
.____       ___________________            __                .__   
|    |     /   _____/\______   \         _/  |_  ____   ____ |  |  
|    |     \_____  \  |    |  _/  ______ \   __\/  _ \ /  _ \|  |  
|    |___  /        \ |    |   \ /_____/  |  | (  <_> |  <_> )  |__
|_______ \/_______  / |______  /          |__|  \____/ \____/|____/\/        \/         \/                                    """print(title)print("当前目录下pic文件夹中存放图片,txt文件夹存放待加密信息和解密信息")while True:choice = input("请输入数字选择功能:1.隐写 2.提取 3.退出 :")if choice=='1':img_src = input('请输入图片路径:')file_src = input('请输入文件路径:')lsb_embed(img_src,file_src)elif choice=='2':img_src = input('请输入图片路径:')file_src = input('请输入文件路径:')lsb_embed(img_src,file_src)lsb_extract(img_src,file_src)else:print("感谢使用,请自行到相应文件夹查看结果")break


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部