LSB图像隐写 python代码

在这里插入图片描述
LSB图片隐写(最低有效位隐写)
https://blog.51cto.com/u_15127612/4109760

原理我直接贴个链接吧,就是把比特信息一位一位的藏在每个像素RGB的最低有效位里,反正人眼没那么敏锐,差这么点看不出来,而且像素本身最后一位是有意义的,本来就不是全零或全一,如果不知道具体藏在哪里的人很难识别并提取出隐藏信息来。

隐写

# -*- coding: UTF-8 -*-
# encode.py

from PIL import Image


def plus(str):
    # Python zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0。
    return str.zfill(8)


def get_key(strr):
    # 获取要隐藏的文件内容
    tmp = strr

    # f = file(tmp,"rb")
    f = open(tmp, "rb")
    str = ""
    s = f.read()

    for i in range(len(s)):
        # 逐个字节将要隐藏的文件内容转换为二进制,并拼接起来
        # 1.先用ord()函数将s的内容逐个转换为ascii码
        # 2.使用bin()函数将十进制的ascii码转换为二进制
        # 3.由于bin()函数转换二进制后,二进制字符串的前面会有"0b"来表示这个字符串是二进制形式,所以用replace()替换为空
        # 4.又由于ascii码转换二进制后是七位,而正常情况下每个字符由8位二进制组成,所以使用自定义函数plus将其填充为8位
#        print("i: s[i]: tmp:",i ,s[i], tmp)
        tmp = s[i]
        # tmp = ord(tmp)
        tmp = bin(tmp)
        str = str + plus(tmp.replace('0b', ''))

    f.closed
    print("str", str)

    return str


def mod(x, y):
    return x % y

# str1为载体图片路径,str2为隐写文件,str3为加密图片保存的路径

def func(str1, str2, str3):
    im = Image.open(str1)

    # 获取图片的宽和高

    width = im.size[0]
    print("width:" + str(width) + "\n")
    height = im.size[1]
    print("height:" + str(height) + "\n")
    count = 0

    # 获取需要隐藏的信息
    key = get_key(str2)
    keylen = len(key)

    for h in range(0, height):
        for w in range(0, width):
            pixel = im.getpixel((w, h))
            a = pixel[0]
            b = pixel[1]
            c = pixel[2]

            if count == keylen:
                break

            # 下面的操作是将信息隐藏进去
            # 分别将每个像素点的RGB值余2,这样可以去掉最低位的值
            # 再从需要隐藏的信息中取出一位,转换为整型
            # 两值相加,就把信息隐藏起来了

            a = a - mod(a, 2) + int(key[count])
            # 上面这句是把信息藏在第八位,下面这个是把信息藏在第七位
            # a = a - (a % 4) + (2 * int(key[count]))

            count += 1

            if count == keylen:
                im.putpixel((w, h), (a, b, c))
                break

            b = b - mod(b, 2) + int(key[count])
            count += 1

            if count == keylen:
                im.putpixel((w, h), (a, b, c))
                break

            c = c - mod(c, 2) + int(key[count])
            count += 1

            if count == keylen:
                im.putpixel((w, h), (a, b, c))
                break

            if count % 3 == 0:
                im.putpixel((w, h), (a, b, c))

    im.save(str3)


# 原图
old = r"E:/face_recognize/GADA-main/imgs_test/Abdullah_Gul_0001.png"

# 处理后输出的图片路径
new = r"E:/face_recognize/GADA-main/imgs_test/Abdullah_Gul_0001_new.png"

# 需要隐藏的信息
enc = r"E:/face_recognize/GADA-main/imgs_test/test.txt"

func(old, enc, new)


提取

# -*- coding: UTF-8 -*-
# decode.py

from PIL import Image


def plus(str):
    # Python zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0。
    return str.zfill(8)

def put_key(dec, strr):
    # 存入隐藏的文件内容
    f = open(dec, "w", encoding='utf-8')

    for i in range(0, len(strr), 8):
        strten = int(strr[i:i+8], 2)
        f.write(chr(strten))



def get_key(strr):
    # 获取要隐藏的文件内容
    tmp = strr

    # f = file(tmp,"rb")
    f = open(tmp, "rb")
    str = ""
    s = f.read()

    for i in range(len(s)):
        # 逐个字节将要隐藏的文件内容转换为二进制,并拼接起来
        # 1.先用ord()函数将s的内容逐个转换为ascii码
        # 2.使用bin()函数将十进制的ascii码转换为二进制
        # 3.由于bin()函数转换二进制后,二进制字符串的前面会有"0b"来表示这个字符串是二进制形式,所以用replace()替换为空
        # 4.又由于ascii码转换二进制后是七位,而正常情况下每个字符由8位二进制组成,所以使用自定义函数plus将其填充为8位

        tmp = s[i]
        # tmp = ord(tmp)
        tmp = bin(tmp)
        str = str + plus(tmp.replace('0b', ''))

    f.closed
    print("str", str)

    return str


def mod(x, y):
    return x % y

# str1为图像路径,str2为解码结果路径,n为密文长度
def func(str1, str2, n):
    n *= 8
    im = Image.open(str1)

    width = im.size[0]
    print("width:" + str(width) + "\n")
    height = im.size[1]
    print("height:" + str(height) + "\n")
    count = 0

    k = []
    # 从图片中提取信息
    for h in range(0, height):
        for w in range(0, width):
            pixel = im.getpixel((w, h))
            a = pixel[0]
            b = pixel[1]
            c = pixel[2]

            if count == n:
                break

#            k[count] = mod(a, 2)
            k.append(mod(a, 2))
            count += 1

            if count == n:
                break

#            k[count] = mod(b, 2)
            k.append(mod(b, 2))
            count += 1

            if count == n:
                break

#            k[count] = mod(c, 2)
            k.append(mod(c, 2))
            count += 1

            if count == n:
                break

#    print(k)
    strr =''.join(str(i) for i in k)

 #   print(strr)
    # 把k中的二进制串转为ascii码
    put_key(dec, strr)


# 解码图像路径
pic = r"E:/face_recognize/GADA-main/imgs_test/Abdullah_Gul_0001_new.png"

# 需要隐藏的信息
dec = r"E:/face_recognize/GADA-main/imgs_test/result.txt"

# 密文位数
num = 64

func(pic, dec, num)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值