【LSB图像低位隐写】字符串隐写

news2024/9/23 23:22:28

按照自己的理解写了一个简单的字符串隐藏在图像中的python代码


前言

脱胎于内容安全的大作业~ 目前第一阶段,只完成了字符串隐藏在图像中

步过图像隐藏在图像应该异曲同工,之后实现~


一、代码

图像的output路径和input路径写死了,这个需要自己调整一下

from PIL import Image
# 定义 ANSI 转义码
green_background = "\033[48;5;113m"
red_background = "\033[48;5;203m"
yellow_background = "\033[48;5;226m"
blue_background = "\033[48;5;159m"
black_font = "\033[30m"
reset = "\033[0m"

###定义的一些具有背景色的print
def greebbk_print(str,end=None):
    if type(str) != type("123"):
        return -1
    print(green_background+black_font+str+reset,end=end)
def redbk_print(str,end=None):
    if type(str) != type("123"):
        return -1
    print(red_background+black_font+str+reset,end=end)
def yellowbk_print(str,end=None):
    if type(str) != type("123"):
        return -1
    print(yellow_background+black_font+str+reset,end=end)
def bluebk_print(str,end=None):
    if type(str) != type("123"):
        return -1
    print(blue_background+black_font+str+reset,end=end)


def string2binstream(string):
    if type(string)!=type('123'):
        redbk_print('[-]Invalid Input!')
        return -1
    string=str(len(string))+':'+string
    binstream=''
    for c in string:
        binstream+=bin(ord(c))[2:].zfill(8)
    return binstream
def binstream2string(binary_str):
    # 检查输入字符串是否只包含 '1' 或 '0'
    string=''
    if not all(bit in '01' for bit in binary_str):
        redbk_print("输入字符串应只包含 '1' 或 '0'.")
        return -1
    for i in range(0,len(binary_str),8):
        string+=chr(int(binary_str[i:i+8],2))
    return string



### 处理RGBA图像的隐写
def RGBA_info(image,binInfo,output_path='output.png'):
    '''
    binInfo形如:'010001100011011110101'
    隐写方法为:
    FOR CLOUMN:
        FOR ROW:
            FOR R->G->B->A:
                FOR MASKBITS
                    REWRITE BIT
    '''
    if image.mode!='RGBA':
        redbk_print('[-] Not [RGBA] image')
        return -1
    
    ### 创建一个等大小的空白画布,以便进行隐写信息添加
    steg_pic=Image.new('RGBA',image.size,(0,0,0,0))

    ### 记录选择的RGBA隐写位
    bitsMask=[]

    ### 选择RGBA隐写的位
    bluebk_print('[~]Now you are going to choose bits you wanna use to hide info in channels:')
    bluebk_print('[~]You have to input numbers from [0,7] splited by comma like: 0,3,7')
    for channel in ['r','g','b','a']:
        yellowbk_print(f'[~]Channel {channel}:')
        try:
            bluebk_print('[~]Input:',end='')
            bits=input().strip(',')
            if not len(bits):
                bitsMask.append([])
                continue
            # print(bits)
            bits=bits.split(',')
            for bit in bits:
                if int(bit)<0 or int(bit)>=8:
                    raise ValueError
            bitsMask.append(bits)
        except ValueError:
            redbk_print('[-]Invalid Input!')
            return -1
    
    ### 开始隐写
    index=0
    cloumn,row=image.size
    for x in range(cloumn):
        for y in range(row):
            pixel=list(image.getpixel((x,y)))
            for channel in range(4):
                if index>=len(binInfo):
                    break
                ### 取出需要修改的掩码
                for bit in bitsMask[channel]:
                    if int(binInfo[index]):
                        pixel[channel]=pixel[channel]|(1<<int(bit))
                    else:
                        pixel[channel]=pixel[channel]&(255-(1<<int(bit)))
                    index+=1
                    if index>=len(binInfo):
                        break
            steg_pic.putpixel((x,y),tuple(pixel))
    steg_pic.save(output_path)
    greebbk_print(f'[+]Success hide info to {output_path}')
                    
### 处理RGBA图像的隐写
def RGBA_reinfo(image,output_path='output.png'):
    '''
    binInfo形如:'010001100011011110101'
    隐写方法为:
    FOR CLOUMN:
        FOR ROW:
            FOR R->G->B->A:
                FOR MASKBITS
                    REWRITE BIT
    '''
    if image.mode!='RGBA':
        redbk_print('[-] Not [RGBA] image')
        return -1
    ### 记录选择的RGBA隐写位
    bitsMask=[]
    ### 选择RGBA隐写的位
    bluebk_print('[~]Now you are going to choose bits you wanna use to hide info in channels:')
    bluebk_print('[~]You have to input numbers from [0,7] splited by comma like: 0,3,7')
    for channel in ['r','g','b','a']:
        yellowbk_print(f'[~]Channel {channel}:')
        try:
            bluebk_print('[~]Input:',end='')
            bits=input().strip(',')
            if not len(bits):
                bitsMask.append([])
                continue
            # print(bits)
            bits=bits.split(',')
            for bit in bits:
                if int(bit)<0 or int(bit)>=8:
                    raise ValueError
            bitsMask.append(bits)
        except ValueError:
            redbk_print('[-]Invalid Input!')
            return -1
        
    binInfo=''
    ### 开始隐写信息回复
    cloumn,row=image.size
    for x in range(cloumn):
        for y in range(row):
            pixel=list(image.getpixel((x,y)))
            for channel in range(4):
                ### 取出需要掩码对应位的信息
                for bit in bitsMask[channel]:
                    binInfo+=str(int((pixel[channel]&1<<int(bit))!=0))

    string=binstream2string(binInfo)
    colon_index=string.index(':')
    length=int(string[:colon_index])
    string2=string[colon_index+1:]
    string2=string2[:length]
    greebbk_print(f'[+]The hidden info: {string2}')

def main(path=None):
    bluebk_print('================================================')
    bluebk_print('Choose the image to hide info:',end='')
    input()
    image=Image.open('cat.png')
    bluebk_print('Enter the string to be hidden:',end='')
    string=input()
    bluebk_print('Input the name of output file:',end='')
    input()
    binstream=string2binstream(string)
    bluebk_print('------------------------------------------------')
    if image.mode=='1':
        yellowbk_print(f'[!]Image Mode:{image.mode} [二值图像]')
        redbk_print('[-]二值图像无法使用LSB低位隐写')
    elif image.mode=='L':
        greebbk_print(f'[+]Image Mode:{image.mode} [灰度图像]')
        yellowbk_print('[!]对灰度值图像进行LSB隐写可能会效果不佳')
    elif image.mode=='P':
        greebbk_print(f'[+]Image Mode:{image.mode} [8位调色板图像]')
        greebbk_print('[+]正在将图像转换为RGBA模式...')
        image=image.convert('RGBA')
        greebbk_print('[+]转换成功')
        greebbk_print('[+]Image Mode:RGBA [真彩色加透明度]')
        RGBA_info(image,binstream)
    elif image.mode=='RGB':
        greebbk_print(f'[+]Image Mode:{image.mode} [真彩色图像]')
        greebbk_print('[+]正在将图像转换为RGBA模式...')
        image=image.convert('RGBA')
        greebbk_print('[+]转换成功')
        greebbk_print('[+]Image Mode:RGBA [真彩色加透明度]')
        RGBA_info(image,binstream)
    elif image.mode=='RGBA':
        greebbk_print(f'[+]Image Mode:{image.mode} [真彩色加透明度')
        RGBA_info(image,binstream)
    else:
        redbk_print('[-]Unknown or Unsupported Mode!')
        return -1
    image2=Image.open('output.png')
    RGBA_reinfo(image2)


if __name__ == '__main__':
    main()
    # string2binstream('abcdefg')
    # binstream2string('01100001011000100110001101100100011001010110011001100111')
    

二、效果

原图

 

隐写后的图

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1906346.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SpringBoot】IDEA查看spring bean的依赖关系

前因&#xff1a;研究springcloud config组件时&#xff0c;我发现config-server包下的EnvironmentController不在扫描的包路径下却可以响应客户端的请求&#xff0c;这引起了我的注意&#xff0c;我的问题是&#xff1a;EnvironmentController是怎么被添加进bean工厂的。本章就…

联系表单提交Contact Form自动发送邮件源码

联系表单Contact Form提交后自动发送邮件源码构建指南&#xff1f; 无论是商业网站、博客还是个人主页&#xff0c;几乎每个网站都会有一个联系表单&#xff0c;用于收集用户的反馈、询问或建议。AokSend将探讨联系表单在网站中的重要性&#xff0c;以及如何通过源码实现自动发…

新加坡工作和生活指北:工作篇

文章首发于公众号&#xff1a;Keegan小钢 一年多以前&#xff08;2022 年 8 月初&#xff09;&#xff0c;那时我过来新加坡才 4 个多月&#xff0c;就写了篇文章分享了当时在新加坡的生活和工作体验。文章得到的反响不错&#xff0c;但也反馈出了一些新的问题&#xff0c;比如…

【数据结构】栈的实现(含详细代码)

文章目录 1.栈1.1 栈的概念及结构1.2 栈的实现1.3 代码实现 1.栈 1.1 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守先进后…

如何监控和优化 PostgreSQL 中的连接池使用?

文章目录 一、连接池的基本概念二、监控 PostgreSQL 连接池使用的重要性&#xff08;一&#xff09;性能优化&#xff08;二&#xff09;资源管理&#xff08;三&#xff09;故障排查 三、PostgreSQL 连接池监控指标&#xff08;一&#xff09;活跃连接数&#xff08;二&#x…

下一代 CSS 框架:Mojo CSS

前言 Tailwind CSS 推出即受到广大开发者的欢迎&#xff0c;当前 Github star 数已达 77.8k。它是一个功能类优先&#xff08;utility-first&#xff09;的 CSS 框架&#xff0c;它提供了一系列功能类&#xff0c;让开发者可以在 HTML 中通过组合这些功能类&#xff08;原子类…

阶段三:项目开发---大数据开发运行环境搭建:任务3:安装配置Hadoop集群

任务描述 知识点&#xff1a;安装配置Hadoop 重 点&#xff1a; 安装配置Hadoop 难 点&#xff1a;无 内 容&#xff1a; Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下&#xff0c;开发分布式程序。充分利用集群的威…

Flink 提交作业的方式

参考&#xff1a; Flink运行方式及对比-腾讯云开发者社区-腾讯云

前端程序员如何转大模型?收藏这一篇就够了(非常详细)

最近各行各业都不容易啊&#xff0c;那个中金女员工跳楼事件频繁上热点&#xff0c;引起广泛的关注&#xff0c;本质上还是经济下行&#xff0c;我们互联网行业也是如此&#xff0c;特别是程序员&#xff0c;本来就有35岁危机&#xff0c;加上行业不景气&#xff0c;大厂都在裁…

C语言中的数组:掌握数据的有序集合【一维数组,二维数组,字符串数组,直方图打印,计算全排列,字符数组常用函数】

目录 C语言中的数组&#xff1a;掌握数据的有序集合【一维数组&#xff0c;二维数组&#xff0c;字符串数组】一维数组一维数组的创建数组的七种初始化完全初始化&#xff1a;部分初始化&#xff1a;字符数组的初始化&#xff1a;自动初始化为0&#xff1a;使用memset函数初始化…

C语言求10进制转2进制(除2取余法)

1.思路&#xff1a;除2取余法&#xff0c;也就是说用除以2取余来将10进制数转换为二进制 2.两种代码实现&#xff0c;这里用了两&#xff0c;一个递归一个非递归。 递归是一种编程技术&#xff0c;其中一个函数直接或间接地调用自己。递归通常用于解决那些可以被分解为更小的、…

QCC5181 歌词歌曲名多国语言显示替代QCC5125 CSR8675

QCC518X作为Qualcomm新一代蓝牙技术芯片&#xff0c;支持最新蓝牙协议V5.4&#xff0c;较QCC512X系列&#xff0c;它有更强大的DSP、CPU。除支持USB、I2S、SPDIF等接口外&#xff0c;还扩展了LE Audio功能&#xff0c;扩展支持AptX Lossless。以5181为例&#xff0c;我们还扩展…

Pandas 学习笔记(四)--CSV文件

CSV文件 CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。 读取与写入 读取csv文件 i…

智能充电(新能源电动车,电单车)云管理系统的定制解决方案

一 系统简介 智能充电&#xff08;新能源电动车&#xff0c;电单车&#xff09;云管理系统 是一套能够实现对充电站/桩的实时通讯、状态监控、故障检测、运营分析、数据统计、策略设置的智能化多任务管理系统。 二 平台概览 智能充电云管理系统 https://chongdianzhuang.itg…

C# CvDnn部署CoupledTPS实现旋转图像矫正

C# CvDnn部署CoupledTPS实现旋转图像矫正 目录 说明 效果 模型信息 项目 代码 下载 说明 TPAMI2024 - Semi-Supervised Coupled Thin-Plate Spline Model for Rotation Correction and Beyond github地址&#xff1a;https://github.com/nie-lang/CoupledTPS 代码实现…

【SpringCloud应用框架】Nacos命名空间、分组和DataID三者关系

第五章 Spring Cloud Alibaba Nacos之命名空间、分组和DataID三者关系 文章目录 一、名词解释三者关系 二、切换不同环境DataID方案Group方案Namespace空间方案 一、名词解释 命名空间&#xff08;Namespace&#xff09; ​用于进行租户粒度的配置隔离。不同的命名空间下&…

C++ 智能指针使用不当导致内存泄漏问题

shared_ptr相互嵌套导致循环引用 代码示例 #include <iostream> #include <memory> using namespace std;class B;class A { public:std::shared_ptr<B> b_ptr;~A() { std::cout << "A destroyed\n"; } };class B { public:std::shared_pt…

优选算法之技巧(一):双指针一:移位0与复写0

引用&#xff1a;我们之前学过快排&#xff0c;首先用三元取中&#xff0c;找(key)&#xff0c;然后就用到了双指针的方法来进行交换排序&#xff0c;那我们今天要讲的双指针其实大同小异&#xff0c;无非在数组中就变成了下标。 题一&#xff1a; 给定一个数组 nums&#xf…

云平台教程 | 手把手教你主成分分析PCA的可视化

爱基百客云平台小工具使用 1.1 爱基百客云平台之PCA分析 1.2 PCA分析原理 1.3 参数设置 1.4 任务查看 1.5 结果 1.5.1 PCA图 01 爱基百客云平台小工具使用 首先&#xff0c;打开爱基百客官网&#xff1a;http://www.igenebook.com&#xff1b;点击菜单栏最右侧“云平台”按钮…

藏汉翻译通工具推荐使用《藏文翻译词典》App:藏族文化的掌上宝典,帮助你了解学习藏语反义词近义词和藏文作文!

如果你正在学习藏语&#xff0c;遇到不同地区的发音不同时&#xff0c;卫藏语、安多语和康巴语&#xff0c;那么你需要一款好用的翻译和语音朗读工具&#xff0c;帮助你掌握藏语。 如果你正在用藏文写作文&#xff0c;发现一些词汇不会时&#xff0c;需要使用藏文词典&#xf…