利用BMP图片水印技术写入加密信息

转载 2013年12月04日 17:02:54

本文主要和大家讨论一下BMP图片水印技术。其实BMP图片水印技术就是在BMP图片中写入编码后的数据,但写入数据后的图片在外观上和原始图片没有区别(只有文件哈希值改变),并能用特定的程序将写入的信息还原出来。
 
BMP图片规格
    BMP图片存放时按照每个像素的RGB信息存储,每个像素的颜色用一个字节(8bit)存放。BMP图片的文件头如图1和图2所示。
图1
图2
0x42、0x4D表示BMP图片的标识;0x36、0x09、0x00、0x00表示BMP图片的文件大小;0x36、0x00、0x00、0x00表示BMP图片的数据区从第几个字节开始;0x00、0x02、0x00、0x00表示BMP图片的像素宽度;0x80、0x01、0x00、0x00表示BMP图片的像素高度;0x18、0x00、0x00、0x00表示BMP图片的每个点的像素值。以上这些特殊字节都是记录BMP图片信息的地方,是不能进行修改的,这就是BMP图片文件头的格式。虽然BMP图片中的一些特殊字节是我们不能修改的,但是BMP图片的数据区是可以修改的,数据区如图3所示,从55字节处开始,其中0xFF、0x00、0x00分别表示RGB信息(0~255)。
图3
 
程序原理
我实现程序的基本原理就是将要写入图片的信息逐一进行二进制编码后,分别写入RGB字节的末尾。例如要将a写入图片中,a的ASCII码97,二进制为0110 0001,原始图片的第55个字节数据区开始的8个字节的信息分别为0x00、0xFF、0x00、0x00、0xFF、0x00、0x00和0xFF,将a的二进制编码写入(为方便起见,编码我采取从右到左的顺序写入),如图4所示。
图4
编码时只需要将二进制写入RGB的末尾,若1写入0x00,只需将“0000 | 0001=0001”,此时0x00就变为0x01;若0写入0xFF,只需将“11111111 & 11111110=11111110”,此时0xFF就变为0xFE。以此类推,这样就可以将a的二进制编码写入RGB的末尾了。由于颜色变化仅仅为0xFF变为0xFE,肉眼是无法分辨出来的。写入a后的图片如图5所示。但是在进行汉字编码的时候,由于汉字使用的是Unicode编码,且由两个负数组成,所以必须加入汉字标识位。
图5
写入代码实现
void write_information()
{
FILE *fp,*ip; //定义了指向BMP图片和文本文件的文件指针
int i=0,input_temp[8]={0,0,0,0,0,0,0,0},j,t=0,x,y,text_ch=0;
int Re_size,input_pointer,bmp_size;
unsigned char bmp_data[8];
char input_data;
//打开BMP图片文件
if((fp=fopen(FileName,"r+b"))==NULL)
{
printf("-->打开BMP文件错误");
exit(1);
}
//打开txt文本文件
if((ip=fopen("input.txt","r"))==NULL)
{
printf("-->打开input文件错误");
exit(1);
}
//判断文本文件大小是否能写入图片,Re_size为返回是否写入判断值
Re_size=Txt_size();
If(Re_size==0)
{
exit(1);
}
//得到输入的文本文件的大小,input_pointer为文件指针的位置
fseek(ip,0,SEEK_END);
input_pointer=ftell(ip);
if(input_pointer==0)
{
printf("-->input.txt文件中的内容为空,请写入数据");
exit(1);
}
printf("-->input.txt文件中现在有:%d个字节",input_pointer);
rewind(ip);
//得到BMP图片的大小,bmp_size为BMP图片文件的大小
fseek(fp,0,SEEK_END);
bmp_size=ftell(fp);
rewind(fp);
}
//将文件指针指向数据区
fseek(fp,55,SEEK_SET);
//清除缓存中的数据流(此函数重要,没有此函数读数据时会有乱码)
fflush(fp);
//进入写入水印数据操作
do
{//读取BMP图片中8个字节的信息,并存入一个临时数组中
for(j=0;j<8;j++)
{
fread(&bmp_data[j],sizeof(unsigned char),1,fp);
}
//将BMP图片指针回8个字节
fseek(fp,-8,SEEK_CUR);
//读取Txt文本文件中的数据
fread(&input_data,sizeof(char),1,ip);
//得到Txt文本读取数据的ASCII值
input_data=(int)input_data;
//判断是字符还是汉字
if(input_data<0)
{
//汉字标识位
text_ch=-1;
input_data=(input_data*-1);
}
j=7;
//将Txt文本数据转换为二进制
do
{
input_temp[j]=input_data%2;
//如果是二进制0,将0写入RGB字节末尾
if(input_temp[j]==0)
{
bmp_data[t]=(bmp_data[t]&254);
fwrite(&bmp_data[t],sizeof(unsigned char),1,fp);
t++;
}
//如果是二进制1,将1写入RGB字节末尾
if(input_temp[j]==1)
{
bmp_data[t]=(bmp_data[t]|1);
fwrite(&bmp_data[t],sizeof(unsigned char),1,fp);
t++;
}
input_data=input_data/2;
j--;
}while(input_data!=0);
For(y=0;y<(j+1);y++)
{//处理Unicode编码的中文汉字,在中文标识位上写入标识1
if(text_ch==-1&&y==j)
{
bmp_data[t]=(bmp_data[t]|1);
fwrite(&bmp_data[t],sizeof(unsigned char),1,fp);
t++;
text_ch=0;
break;
}
//转换后的二进制不足八位其余位补0
bmp_data[t]=(bmp_data[t]&254);
fwrite(&bmp_data[t],sizeof(unsigned char),1,fp);
t++;
}
j=7;
t=0;
fflush(fp);
//恢复临时文本数组
for(x=0;x<8;x++)
{
input_temp[x]=0;
}
i++;
}while(i!=input_pointer);

读取代码实现
void read_information()
{
FILE *fp;
int i,j=55,t,temp=1,k,add=0,show[2]={0,0},inshow,x=0,y;
unsigned char bmp_data[8]={0,0,0,0,0,0,0,0};
if((fp=fopen(FileName,"r+b"))==NULL)
{
printf("-->打开BMP图片文件错误");
exit(1);
}
fseek(fp,55,SEEK_SET);
//清除缓存中的数据流(此函数重要,没有此函数读数据时会有乱码)
fflush(fp);
do
{
//将BMP图片RGB信息读取出来
for(i=0;i<8;i++)
{
fread(&bmp_data[i],sizeof(unsigned char),1,fp);
j++;
}
//判断读取完毕的条件
if(j>end_pointer)
{
break;
}
//将二进制信息从RGB末字节处取出
for(t=0;t<8;t++)
{
bmp_data[t]=(bmp_data[t]&1);
}
//将二进制信息还原
add=bmp_data[0]*1;
for(k=1;k<7;k++)
{
temp*=2;
add+=(bmp_data[k]*temp);
}
//判断是否是中文编码的字符
if(bmp_data[7]==0)
{
inshow=add;
printf("%c",inshow);
}
if(bmp_data[7]==1)
{
show[x]=add;
show[x]=(show[x]*-1);
x++;
}
//还原临时BMP图片数组初始值
for(y=0;y<8;y++)
{
bmp_data[y]=0;
}
temp=1;
add=0;
//显示中文字符
if(x==2)
{
printf("%c%c",show[0],show[1]);
x=0;
}
}while(1);
printf("-->读出BMP图片文件中的信息完成");
fcloseall();
}
总结
在BMP图片中写入水印,只要从数据区55个字节以后都可以每8个RGB字节末尾写入二进制信息,如0xFF变为0xFE(Red值从255变为254),这样图片的变化情况是无法用肉眼来分辨的,只有文件的哈希值会改变,这样就能将一些加密信息写入其中了

简单的数字水印加密技术

最近我一个朋友问谍战情节里是怎样办到将数据隐藏到一般图片里的,正好有一段时间我也研究过这个问题,既然他问了干脆我就写出来和大家也一起分享一下吧,大都是自己琢磨的,如有更加专业的做法欢迎大家讨论啊。 由...
  • WBLCT
  • WBLCT
  • 2013年07月28日 14:41
  • 2290

利用BMP图片水印技术写入加密信息

文/图 [黑防vip]lwt831120 本文主要和大家讨论一下BMP图片水印技术。其实BMP图片水印技术就是在BMP图片中写入编码后的数据,但写入数据后的图片在外观上和原始图片没有区别(只有文件哈...

初探无水印信息图片加密技术

原文链接 https://yq.aliyun.com/articles/72267 背景 随着手机app越来越多,对于App信息安全面临的挑战越来越大,像接口传递的验证信息这些相对保密的信息如果直...

DirectShow中利用SampleGrabber捕获摄像头每一帧图像,并转为BMP文件信息写入内存

关于怎样枚举设备、建立Filter Graph等问题,我就不多说了,说也说不清楚,因为我也是才接触DirectShow。网上这类资料还是很多,百度知道的比我多多了。这里主要介绍一下自己在学习了Stil...

BMP水印技术加解密的应用

  • 2009年12月24日 20:46
  • 7KB
  • 下载

Itext生成PDF文件加密与加水印 ( 2008-07-17 11:35:33| 分类: java 技术)

最近的项目中使用Itext将txt文件转换为PDF文件,并且实现对文件的一些权限控制现实对pdf文件加密,添加水印等最主要的是要实现对pdf文件实现密钥签名,一直都还没有实现成功!等实现好了后再加上来...

txt转BMP图片信息

  • 2013年06月21日 18:49
  • 6.6MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用BMP图片水印技术写入加密信息
举报原因:
原因补充:

(最多只允许输入30个字)