分享

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

 笔录收藏 2021-12-20

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个字节。 24位bmp图像数据结构

3.程序设计思路

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

4.代码

01//hid.cpp  by kryptosx
02//隐藏程序代码
03#include <iostream>
04#include <fstream>
05#include <bitset>
06#include<cstdlib>
07#include "stdio.h"
08using namespace std;
09string pstr;
10string tstr;
11string stemp;
12const int py=54;             //数据区开始位置(因为从0算起)
13int main(int argc, char* argv[])
14{
15    if(argc!=3)
16    {
17        puts("error:参数错误");
18        return 0;
19    }
20    ifstream pic(argv[1]);
21    ifstream txt(argv[2]);
22    if(!pic.is_open() || !txt.is_open())
23    {
24        perror("文件打开失败");
25        return 0;
26    }
27    while(getline(pic,stemp))
28    {
29        pstr+=stemp;
30        stemp.clear();
31    }
32    while(getline(txt,stemp))
33    {
34        tstr+=stemp;
35        stemp.clear();
36    }
37    int pl=pstr.size();
38    int tl=tstr.size();    
39
40    if(tl>100)
41    {
42        puts("字符过多");
43        printf("%d",tl);
44        return 0;
45    }
46    if(tl==0)
47    {
48        puts("没有字符");
49        return 0; 
50    }
51    int ty=(pl-py)/(tl*8);        //计算间隔
52    int tp=rand()%256;
53    pstr[6]=tl^tp;
54    pstr[7]=tp;            //记录隐藏信息的长度到保留区中
55    for(int i=py,j=0;j!=tl;++j)          //把隐藏的信息转化成bit,写入到间隔的字节的最后一位。
56    {
57         bitset<8> bt(tstr[j]);
58         for(int k=0;k!=8;k++)
59         {
60             if(bt[8-k-1]==true) pstr[i]|=1;      
61             else pstr[i]&=~1;           
62             i+=ty;
63         }
64    }
65    ofstream out("out.bmp");
66    out<<pstr<<endl;
67    pic.close();          //关闭文件流
68    txt.close();
69    out.close();
70    return 0;
71}
01//creck.cpp by kryptosx
02//数据提取代码
03#include <iostream>
04#include <fstream>
05#include <bitset>
06#include<cstdlib>
07#include "stdio.h"
08using namespace std;
09string pstr;
10sring stemp;
11const int py=54;
12int main(int argc, char* argv[])
13{
14    if(argc!=2)
15    {
16        puts("error:参数错误");
17        return 0;
18    }
19    ifstream pic(argv[1]);
20    if(!pic.is_open())
21    {
22        perror("文件打开失败");
23        return 0;
24    }   
25    while(getline(pic,stemp))
26    {
27        pstr+=stemp;
28    }
29
30    int pl=pstr.size(); 
31    int tl=pstr[6]^pstr[7];         //从保留区提取出隐藏信息的长度 
32    int ty=(pl-py)/(tl*8);       //计算间隔 
33
34    char temp=0;
35    ofstream out("out.txt");
36    for(int i=py,j=0;j!=tl;++j)   //提取每个隐写字节末尾的bit,然后重组成隐藏信息。 
37    {
38         temp=0;
39         for(int k=0;k!=8;k++)
40         {
41             temp<<=1;
42             temp+=bitset<8>(pstr[i])[0];
43             i+=ty;

         }
45         out<<temp;
46    }
47close();
48    out.close();
49    return0;
50}

 5.总结

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多