BMP图像信息隐藏
图像隐写算法LSB—Least Significant Bits,又称最不显著位。LSB算法就是将秘密信息嵌入到载体图像像素值得最低有效位,改变这一位置对载体图像的品质影响最小。
原理如下:
以实验用的24位真彩图为例,每个像素用3Byte表示,每Byte分别表示R、G、B三色的亮度,亮度取值范围位0~0xFF。采用LSB算法就是将图像信息的每一Byte的最后一位二进制替换为待嵌入的秘密信息的一位,按顺序进行。因为对最后一位的替换操作其实就是对亮度信息的加一或减一,对颜色影响甚微,所以肉眼难以察觉,这就达到了隐藏信息的目的。对于24位真彩图,所能嵌入的最大秘密信息的大小为像素数量的3/8字节
步骤如下:
- 以二进制的方式读取载体图像并分别头数据与像素数据
- 用二进制秘密信息中的每一笔特信息替换与之对应的载体数据的最低有效位
- 利用得到的新的二进制数据构造图像,即得到含有秘密信息的隐秘图像
/***
change.c
***/
#include<stdio.h>
#include<stdlib.h>
#include"define.h" int main()
{ //创建头文件,信息头结构变量
BMP_FILE_HEADER fileHeader;
BMP_INFO_HEADER infoHeader; //打开载体图像文件,新建修改后的图像文件
FILE *file = fopen("football.bmp","rb");
FILE *newFile = fopen("change.bmp","wbx"); //读取文件头,信息头
fread(&fileHeader,,,file);
fread(&infoHeader,,,file); //读取24位真彩图像的像素信息
RGB *img = (RGB *)malloc(infoHeader.sizeImage);
fread(img,infoHeader.sizeImage,,file); printf("Picture Size(width x height):%d x %d \n", infoHeader.width, infoHeader.height); //对图片内容进行修改,每隔五个像素染黑一个像素
int i = ;
for (i = ; i < infoHeader.sizeImage / ; i += )
{
img[i].red = ;
img[i].green = ;
img[i].blue = ;
}
printf("fwirte\n"); //将新的二进制文件写入到新文件中
fwrite(&fileHeader,,,newFile);
fwrite(&infoHeader,,,newFile);
fwrite(img,infoHeader.sizeImage,,newFile); fclose(file);
fclose(newFile);
return ;
}
修改图像内容的核心代码如下:
int i = ;
for (i = ; i < infoHeader.sizeImage / ; i += )
{
img[i].red = ;
img[i].green = ;
img[i].blue = ;
}
infoHeader.sizeImage表示图像数据的字节数,在24位真彩位图中,表示每个像素需要三个字节,infoHeader.sizeImage/3表示位图总像素数
循环体中将每个颜色分量的亮度赋值为0,让像素变黑,最终得到修改后的图像。
以上是处理BMP图像信息的原理。
下面通过LSB算法隐藏秘密信息,这里把define.h文件作为秘密信息隐藏,也可以选择任何大小合适的文件作为秘密信息。
/***
define.c
***/ typedef unsigned short WORD; //2 byte
typedef unsigned int DWORD; //4 byte
typedef unsigned char BYTE; //1 byte //head of file
typedef struct BMP_FILE_HEADER
{
WORD type;
DWORD size;
WORD reserved1;
WORD reserved2;
DWORD offBits;
}BMP_FILE_HEADER; //head of infomation
typedef struct BMP_INFO_HEADER
{
DWORD size;
int width;
int height;
WORD planes;
WORD bitCount;
DWORD compression;
DWORD sizeImage;
int xPelsPerMeter;
int yPelsPerMeter;
DWORD colorUsed;
DWORD colorImportant;
}BMP_INFO_HEADER; //RGBQUAD
typedef struct RGBQUAD
{
BYTE blue;
BYTE green;
BYTE red;
BYTE reserved;
}RGBQUAD; //RGB
typedef struct RGB
{
BYTE blue;
BYTE green;
BYTE red;
}RGB;
隐藏信息代码:
/***
hide.c
***/
#include<stdio.h>
#include<stdlib.h> #include<sys/stat.h>
#include<unistd.h> #include"define.h" //获取文件大小
int getFileSizeSystemCall(char *strFileName)
{
struct stat temp;
stat(strFileName,&temp);
return temp.st_size;
} int main()
{
//创建文件头,信息头结构体变量
BMP_FILE_HEADER fileHeader;
BMP_INFO_HEADER infoHeader; //打开载体图像文件,读取文件头和信息头,打开隐秘图像信息
FILE *file = fopen("football.bmp","rb");
FILE *newFile = fopen("hide.bmp","wbx");
fread(&fileHeader,,,file);
fread(&infoHeader,,,file); //读取秘密信息文件“define.h”
int infoSize = getFileSizeSystemCall("define.h");
printf("info size : %d\n",infoSize);
BYTE *info = (BYTE *)malloc(infoSize);
FILE *infoFile = fopen("define.h","rb");
fread(info,infoSize,,infoFile); //读取24位真彩图像像素信息
BYTE *img = (BYTE *)malloc(infoHeader.sizeImage);
fread(img,infoHeader.sizeImage,,file); printf("Picture Size (Width x height) : %d x %d\n",infoHeader.width,infoHeader.height);
printf("Can hide %d byte infomation\n",infoHeader.sizeImage/); //LBS算法实现,把隐秘信息的每一个字节8bit按照低字节到高字节的顺序隐藏到像素信息的
//每8byte中的最低位
int i = ,j = ;
BYTE tmp = 0x00;
for(i = ; i < infoSize; i++)
{
for(j = ; j < ; j++)
{
tmp = info[i] &0x01;
if(tmp)
{
img[i*+j] = img[i * + j] | 0x01;
}
else
{
img[i*+j] = img[i * + j] & 0xfe;
}
info[i] = info[i] >> ;
}
} //将修改后的二进制数据写入到隐秘图像文件中
fwrite(&fileHeader,,,newFile);
fwrite(&infoHeader,,,newFile);
fwrite(img,infoHeader.sizeImage,,newFile); fclose(file);
fclose(newFile);
return ;
}
LSB算法实现:
int i = ,j = ;
BYTE tmp = 0x00;
for(i = ; i < infoSize; i++)
{
for(j = ; j < ; j++)
{
tmp = info[i] &0x01;
if(tmp)
{
img[i*+j] = img[i * + j] | 0x01;
}
else
{
img[i*+j] = img[i * + j] & 0xfe;
}
info[i] = info[i] >> ;
}
}
info[i]是存储秘密信息的数组,通过把像素Byte数据与0x01按位或运算使得最后一位为1,通过把像素Byte数据与0xfe(1111,1110)做按位与运算使得最后一位为0(0 & x = 0)
stat函数用来获取指定路径下文件或文件夹的属性。路径可以不指定。
使用md5sum命令查看两张图片的MD5 HASH值
再对比一下文件的16进制内容,先使用xxd命令生成16进制内容:
xxd football.bmp > football.hex
xxd hide.bmp > hide.hex
再使用sed命令查看对比第五行内容
sed -n 5p football.hex
sed -n 5p hide.hex
很明显的可以看到像素数据的每一字节的最后一位发生了变化,验证了LSB算法的原理。
提取信息
/***
extract.c
***/
#include<stdio.h>
#include<stdlib.h>
#include"define.h" int main()
{
//创建头文件,信息头结构体变量
BMP_FILE_HEADER fileHeader;
BMP_INFO_HEADER infoHeader; //读取隐秘图像文件,创建秘密信息文件
FILE *file = fopen("hide.bmp","rb");
FILE *extractFile = fopen("extract.txt","wbx");
BYTE *info = (BYTE *)malloc(); //读取头文件,信息头
fread(&fileHeader,,,file);
fread(&infoHeader,,,file); //读取24位真彩图像的像素信息
BYTE *img = (BYTE *)malloc(infoHeader.sizeImage);
fread(img,infoHeader.sizeImage,,file); printf("Picture size : %d x %d \n",infoHeader.width,infoHeader.height); //信息提取部分,根据秘密信息的长度,依次读取隐秘图像信息像素信息的最低bit,凭借成Byte
int i = ,j = ;
BYTE tmp = 0x00,ttmp = 0x00;
for(i = ; i < ; i++)
{
tmp = 0x00;
for(j = ; j < ; j++)
{
/*取每8位bit像素信息的最后一位拼接为1Byte的秘密信息*/
ttmp = img[i*+j] & 0x01;
ttmp = ttmp << j; //左移j位
tmp += ttmp; //每一位累加得到1Byte的tmp值
}
info[i] = tmp;
} //将提取的信息写入到秘密文件中
fwrite(info,,,extractFile); fclose(file);
fclose(extractFile);
return ;
}
使用md5sum查看两个文件是否相同
md5sum define.h extract.txt
提取过程就是隐藏过程的逆过程,实现原理和隐藏过程类似。需要注意的是,此处使用的文件长度是固定的秘密信息的长度,并且提前知道了隐藏信息包含在了指定图片中。在实际处理中,在隐藏秘密信息时,往往还需要一个嵌入标识和长度信息,来帮助程序判断图片中是否包含秘密信息,并说明秘密信息长度
拓展
修改 hide.c 并使用手动输入的数字作为密钥来规定秘密信息隐藏与载体图片的起始位置。
修改 extract.c 并根据输入的秘钥提取秘密信息
每 Byte 像素信息隐藏 2bit 的秘密信息(MLSB 算法)
BMP图像信息隐藏的更多相关文章
- BMP 图像信息隐藏及检测
原理简介 针对文件结构的信息隐藏方法需详细掌握文件的格式,利用文件结构块之间的关系或根据块数据和块大小之间的关系来隐藏信息. BMP(Bitmap-File)图形文件是 Windows 采用的常见图形 ...
- Python实现图像信息隐藏
Python实现图像信息隐藏 之前学习密码学的时候老师有提到过『信息隐藏』,现在用图像的方法尝试一下.思想是:把信息藏到RGB通道中的B通道,然后利用奇偶性可以恢复过来 原理 从源图中提取文字图像信息 ...
- Windows 备用数据流(ADS)的妙用___转载
NTFS交换数据流(Alternate Data Streams,简称ADS)是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流.通俗的理解,就是其它文件可以“寄宿”在某 ...
- delphi视频聊天
用Delphi开发视频聊天软件 一.引言 我们知道视频聊天软件的关键技术在于采集视频,并实时传输给聊天软件在线的人.对于视频的采集,这里采用微软公司的关于数字视频的一个软件包VFW(Video for ...
- 用Delphi开发视频聊天软件
摘要:目前网上视频聊天软件.视频会议软件.可视IP电话软件随处可见,你是否想自己做一个玩玩?其实这类软件无非是视频加上网络而建成的.如果熟悉视频捕捉和网络传输技术,根本就难不倒你.微软为软件开发人员提 ...
- 60701BMP彩色图像转化为灰度及二值图像
1 概述 多媒体技术是一门综合了多种学科的新技术,其涉及到计算机科学与技术.通信和网络技术.人工智能技术.微电子技术.数字信号处理.图形处 理技术.声像技术等诸多学科.许多新技术的不断出现和体验,带给 ...
- 将文件内容隐藏在bmp位图中
首先要实现这个功能,你必须知道bmp位图文件的格式,这里我就不多说了,请看:http://www.cnblogs.com/xiehy/archive/2011/06/07/2074405.html 接 ...
- BMP文件格式分析
前两天要做一个读取bmp文件的小程序,顺便查找了一些关于BMP格式的文章,现在post上来. 简介 BMP(Bitmap-File)图形文件是Windows采用的图形文件格式,在Windows环境下运 ...
- 注册表-各种功能-隐藏IE、隐藏硬盘、禁用硬件
1.在[我的电脑]上隐藏软驱 在[开始]→[运行]→输入[Regedit]→[HKEY_CURRENT_USER]→[Software] →[Microsoft] →[Windows]→[Curren ...
随机推荐
- netcore 实现跨应用的分布式session
需求场景 网站a,域名为 a.site.com 网站b, 域名为 b.site.com 需要在a.b两个站点之间共享session 解决方案 使用redis作为分布式缓存存储 设置sessionId ...
- 两个integer比较时为什么有时候会失效?
当数值不在 -128~127范围时就不会进行缓存操作,它会选择进行new integer()的操作.这样他们被分配到堆里面.[这个可以去查看integer.valueof()的源码].在用==或者!= ...
- 易百教程人工智能python修正-人工智能NLTK性别发现器
在这个问题陈述中,将通过提供名字来训练分类器以找到性别(男性或女性). 我们需要使用启发式构造特征向量并训练分类器.这里使用scikit-learn软件包中的标签数据. 以下是构建性别查找器的Pyth ...
- 溢出处理、盒子模型、背景图片、float(浮动)
一.overflow:溢出内容的处理 overflow:hidden; 溢出内容隐藏(在父元素内使用,可以清除子元素浮动对父元素的影响) overflow:auto; 自动滚动(有溢出 ...
- 推荐一个去除图片人物背景的工具Removebg
可以在线使用,url:https://www.remove.bg/users/sign_in 用邮箱免注册一个免费账号: 注册的邮箱会收到一封激活账号的邮件: 点击Activate account后激 ...
- MySQL Backup--Xtrabackup介绍
Xtrabackup介绍 Xtrabackup是由Percona公司研发的开源热备工具,支持MYSQL 5.0 以上版本. 由于Xtrabackup支持备份innodb表,实际生产环境中我们使用的工具 ...
- Spring AOP无法拦截内部方法调用
当在同一个类中,A方法调用B方法时,AOP无法工作的问题 假设一个接口里面有两个方法: package demo.long; public interface CustomerService { pu ...
- rsa公钥和私钥到底哪个才是用来加密,哪个用来解密?
本文转自:91博客:原文地址:http://www.9191boke.com/138589019.html 公钥和私钥在一些银行系统.第三方支付系统SDK中经常会遇到,刚接触公钥私钥的朋友们估计很难区 ...
- Windows定时任务下载linux服务器批量文件到本地
编写批文件 1.1 编写main.bat文件 E: cd logs ftp -n -s:"E:\logs\mget.bat" 1.2 编写mget.bat文件 open ip地址 ...
- 如何在Jenkins中使用日期参数(变量)
一.首先需要安装插件:Date Parameter Plugin 二.安装完成后,在项目中添加参数,我这里只有日期,时间的话没试过,应该也可以把 三.用${date}调用参数即可 最后邮件的附件正常~