前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于24位bmp图片数据区隐写的实现

基于24位bmp图片数据区隐写的实现

作者头像
sean.liu
发布2022-08-03 14:51:39
1.3K0
发布2022-08-03 14:51:39
举报

1,关于数据区隐写

数据区隐写,即将数据写入到数据区中。相比文件外壳隐写和保留区隐写,更为隐蔽,隐藏的信息容量相对较大。在数据区隐写会造成图像变化,所以需要控制写入方式,以及改写量。使得在普通肉眼难以辨别的更改中实现数据的隐藏。至于其他的隐写方法请看:简单信息隐藏技术的实现与讨论

2,24位bmp图像简介

要在bmp图像进行数据区隐写,必须要知道它的数据结构。否则,可能会破坏图像。 这是bmp的文件结构。

  1.     位图文件头(bitmap-file header)包含了图像类型、图像大小、图像数据存放地址和两个保留未使用的字段。(14字节)
  2.     位图信息头(bitmap-information header)(40字节)
  3.     彩色表/调色板(color table)24位bmp图没有调色板
  4.     位图数据(bitmap-data)

24位bmp图像数据存储的是实际的颜色数据,每个像素用3字节表示,分别是红绿蓝。文件头和信息头共占了54个字节

3.程序设计思路

将bmp和txt读入之后,其实就是两个字符串。接下来要做的就是设计一个算法让它们合并。 考虑到如果直接替换数据区字符。会使像素点有巨大改变。所以,每个字符我只改末尾的一个bit,这样一来,像素点的变化会非常小,几乎没有区别。而且,我尽可能让更改的bit分散在数据区。为了方便提取,我在保留区记录了两个值,他们的异或值就是数据区隐藏信息字节的间隔值。

4.代码

代码语言:javascript
复制
//hid.cpp  by kryptosx
//隐藏程序代码
#include <iostream>
#include <fstream>
#include <bitset>
#include<cstdlib>
#include "stdio.h"
using namespace std;
string pstr;
string tstr;
string stemp;
const int py=54;             //数据区开始位置(因为从0算起)
int main(int argc, char* argv[])
{
    if(argc!=3)
    {
        puts("error:参数错误"); 
        return 0;
    }
    ifstream pic(argv[1]);
    ifstream txt(argv[2]);
    if(!pic.is_open() || !txt.is_open())
    {
        perror("文件打开失败"); 
        return 0;
    } 
    while(getline(pic,stemp))
    {
        pstr+=stemp;
        stemp.clear();
    }
    while(getline(txt,stemp))
    {
        tstr+=stemp;
        stemp.clear();
    }
    int pl=pstr.size();
    int tl=tstr.size();    

    if(tl>100)
    {
        puts("字符过多");
        printf("%d",tl);
        return 0;
    }
    if(tl==0)
    {
        puts("没有字符");
        return 0; 
    }
    int ty=(pl-py)/(tl*8);        //计算间隔
    int tp=rand()%256;
    pstr[6]=tl^tp;
    pstr[7]=tp;            //记录隐藏信息的长度到保留区中
    for(int i=py,j=0;j!=tl;++j)          //把隐藏的信息转化成bit,写入到间隔的字节的最后一位。
    {
         bitset<8> bt(tstr[j]);
         for(int k=0;k!=8;k++)
         {
             if(bt[8-k-1]==true) pstr[i]|=1;       
             else pstr[i]&=~1;           
             i+=ty;
         }
    }
    ofstream out("out.bmp");
    out<<pstr<<endl;
    pic.close();          //关闭文件流
    txt.close();
    out.close();
    return 0;
}
代码语言:javascript
复制
//creck.cpp by kryptosx
//数据提取代码 
#include <iostream>
#include <fstream>
#include <bitset>
#include<cstdlib>
#include "stdio.h"
using namespace std;
string pstr;
string stemp;
const int py=54;
int main(int argc, char* argv[])
{
    if(argc!=2)
    {
        puts("error:参数错误"); 
        return 0;
    }
    ifstream pic(argv[1]);
    if(!pic.is_open())
    {
        perror("文件打开失败"); 
        return 0;
    }    
    while(getline(pic,stemp))
    {
        pstr+=stemp;
    }

    int pl=pstr.size(); 
    int tl=pstr[6]^pstr[7];         //从保留区提取出隐藏信息的长度 
    int ty=(pl-py)/(tl*8);       //计算间隔 

    char temp=0;
    ofstream out("out.txt");
    for(int i=py,j=0;j!=tl;++j)   //提取每个隐写字节末尾的bit,然后重组成隐藏信息。 
    {
         temp=0;
         for(int k=0;k!=8;k++)
         {
             temp<<=1;
             temp+=bitset<8>(pstr[i])[0];
             i+=ty;
         }
         out<<temp;
    }
    pic.close();
    out.close();
    return 0;
}

 5.总结

这是一个很简单的图片数据区隐写程序,基于24位bmp图像。基本实现了需要的功能,分散的写入使得肉眼难以发现异常,其次,无需原图也可以提取信息。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014年4月19日1,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1,关于数据区隐写
  • 2,24位bmp图像简介
  • 3.程序设计思路
  • 4.代码
  •  5.总结
相关产品与服务
图数据库 KonisGraph
图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档