基于python的LSB加密算法设计

任务

编程实验,实现基于LSB算法的,在图片中进行信息隐藏的程序,并用自己的姓名或者学号作为要隐藏的信息。

1.首先明确操作的原理

原理
LSB全称为 least significant bit,是最低有效位的意思。Lsb图片隐写是基于lsb算法的一种图片隐写术,这是一种常见的信息隐藏方法。LSB算法是将信息的每一位隐藏到图片RGB单元的最后一位,由于一位的改变对于颜色影响不大,人的肉眼难以识别,从而达到信息隐藏的效果。

相关信息的补充
首先来讲png图片,png图片是一种无损压缩的位图片形格式,也只有在无损压缩或者无压缩的图片(BMP)上实现lsb隐写。如果图像是jpg图片的话,就没法使用lsb隐写了,原因是jpg图片对像数进行了有损压缩,我们修改的信息就可能会在压缩的过程中被破坏。而png图片虽然也有压缩,但却是无损压缩,这样我们修改的信息也就能得到正确的表达,不至于丢失。BMP的图片也是一样的,是没有经过压缩的。BMP图片一般是特别的大的,因为BMP把所有的像数都按原样储存,没有进行压缩。
png图片中的图像像数一般是由RGB三原色(红绿蓝)组成,每一种颜色占用8位,取值范围为0x00~0xFF,即有256种颜色,一共包含了256的3次方的颜色,即16777216种颜色。而人类的眼睛可以区分约1000万种不同的颜色,这就意味着人类的眼睛无法区分余下的颜色大约有6777216种。所以用LSB算法可以达到信息隐藏的效果。

2.进行操作的思如如下

2.1隐藏信息

①首先准备好要读取的图片,和要加密的数据。
②然后将要加密的数据化转化为2进制字符串。
③然后,读取图片数据为3维数组,找到n个点,(n等于要加密2进制字符串的长度)。
④将③中的图片上的点,按顺序,对每个点所存储的数据,转化为2进制,然后将最后一位bit 位的数据,按顺序替换为要加密的2进制字符。
⑤将替换后的图像的3维数组数据保存输出为图像,即为隐藏了加密信息的图片。

2.2读取隐藏信息

①读取加密后的图片的信息为3维数组。
②找到依次加密的点的数据,将最后一位bit位上的数合并起来得到加密的二进制字符串。
③将加密的二进制字符串转还原为解密后的数据。

3.遇到的问题

①cv2库的imread读取路径不能包含中文。
②隐藏中文和数字的方式不同,所以设置了2种方式,实现分别对中文和数字的隐藏。

补充的python函数内容

主要是字符串、数字、中文间的转化:

可以参考的文章:
python(中文、数字(2进制、10进制、16进制)、字符串)之间的转换

4.具体的操作代码的如下

用到的工具:python。

4.1读取图片数据

import random
import cv2
import  copy
#读取一副图片
image=cv2.imread(r'C:\Users\yunmeng\Desktop\1.png')
#修改前的图像
pre_image=copy.deepcopy(image)
#待修改的图像的数据
after_image=copy.deepcopy(image)

读取后的图片的信息为3维的数组据矩阵如下
在这里插入图片描述
请添加图片描述

4.2隐藏(数字数据),各函数的设计

①隐藏数据函数

def disguise(pre_image,disguise_information):
    #获取读到图片的信息
    mysize=after_image.shape
    #需隐藏的图片的信息
    message=bin(disguise_information).replace('0b','')
    l=len(message)
    #这里采用集合对点的数据进行存储,为了不让点出现重复
    m_n_list=set([])
    #要替换的位置坐标(m,n)
    def generate_random(count):
        if(len(m_n_list)<count):
            m=random.randrange(0,mysize[0],1)
            n=random.randrange(0,mysize[1],1)
            tem=(m,n)
            m_n_list.add(tem)
            generate_random(count)
    random.seed(1)
    generate_random(l)
    m_n_list=list(m_n_list)
    #进行数据的替换
    for i in range(l):
        replace_num = after_image[m_n_list[i][0], m_n_list[i][1], 1]
        tem_str = bin(replace_num)[:-1] + message[i]
        tem_num=int(tem_str.replace('0b', ''), 2)
        after_image[m_n_list[i][0], m_n_list[i][1], 1]=tem_num
    #保存图片
    cv2.imwrite(r'C:\Users\yunmeng\Desktop\2.png',after_image)
    #将加密所在的位置m,n,数据进行存储。
    with open(r'D:\Users\yunmeng\PycharmProjects\数据分析\课程作业相关代码文件\lsb算法加密\m_n','w') as f:
            f.write(str(m_n_list))
    return m_n_list

②进行数据的隐藏,同时保存图片中隐藏的点的位置的数据。

m_n=disguise(pre_image,20210010001)

③定义读取隐藏信息的函数

def gain_password(after_image,m_n_list):
    #读取加密的图片文件
    #after_image=cv2.imread(path)
    password=[]
    for j in range(len(m_n_list)):
        m=m_n_list[j][0]
        n=m_n_list[j][1]
        tem_num=after_image[m,n,1]
        tem_str = bin(tem_num)[-1]
        password.append(tem_str)
    password=''.join(password)
    password=int(password,2)
return  password

④读取隐藏信息

gain_Password=gain_password(after_image,m_n)
print('gain_Password:',gain_Password)

结果如下图:
在这里插入图片描述

4.4.加密前后的图像的对比

左前,右后。
在这里插入图片描述

可以看出加密前后,除了像素点不同外,几乎看不出其他的任何变化。

4.3隐藏(中文数据),函数的设计

①隐藏数据函数


def disguise(pre_image,disguise_information,):
    #获取读到图片的信息
    mysize=after_image.shape
    #需隐藏的图片的信息
    whole_word = ''
    word_sep = []
    tem_sep = 0
    for i in disguise_information:
        single_word = format(ord(i), 'b')
        whole_word += single_word
        l = len(single_word)
        tem_sep += l
        word_sep.append(tem_sep)
    message=whole_word
    l=len(message)
    m_n_list=set([])
    #要替换的位置坐标(m,n)
    def generate_random(count):
        if(len(m_n_list)<count):
            m=random.randrange(0,mysize[0],1)
            n=random.randrange(0,mysize[1],1)
            tem=(m,n)
            m_n_list.add(tem)
            generate_random(count)
    random.seed(1)
    generate_random(l)
    m_n_list=list(m_n_list)
    #进行数据的替换
    for i in range(l):
        replace_num = after_image[m_n_list[i][0], m_n_list[i][1], 1]
        tem_str = bin(replace_num)[:-1] + message[i]
        tem_num=int(tem_str.replace('0b', ''), 2)
        after_image[m_n_list[i][0], m_n_list[i][1], 1]=tem_num
    #保存图片
    cv2.imwrite(r'C:\Users\yunmeng\Desktop\2.png',after_image)
    #将加密所在的位置m,n,数据进行存储。
    with open(r'D:\Users\yunmeng\PycharmProjects\数据分析\课程作业相关代码文件\lsb算法加密\m_n','w') as f:
            f.write(str(m_n_list))
            f.write('\n')
            f.write(str(word_sep))
    return m_n_list,word_sep

②进行数据的隐藏,同时保存图片中隐藏的点的位置的数据。

m_n,sep=disguise(pre_image,'云梦之上')

③定义读取隐藏信息的函数

def gain_password(after_image,m_n_list,sep):
    #读取加密的图片文件
    #after_image=cv2.imread(path)
    password=[]
    for j in range(len(m_n_list)):
        m=m_n_list[j][0]
        n=m_n_list[j][1]
        tem_num=after_image[m,n,1]
        tem_str = bin(tem_num)[-1]
        password.append(tem_str)
    password=''.join(password)
    chinese_words=[]
    for i in range(len(sep)):
        if i==0:
            tem_word = password[0:sep[i]]
        else:
            tem_word=password[sep[i-1]:sep[i]]
        word=chr(int(tem_word,2))
        chinese_words.append(word)
return  chinese_words

④读取隐藏信息

gain_Password=''.join(gain_password(after_image,m_n,sep))
print('gain_Password:',gain_Password)

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值