VC实现数字水印设计报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机科学与技术学院信科专业综合实践设计报告
专业:电子信息科学与技术
《
班级:信科07-4班
设计题目: VC实现数字水印的加入与提取
成员:姚万华
指导教师:
~
2010年 10月 14日
、
课程设计指导教师评阅书指导教师评语:
`
)
$
[
成绩:指导教师签字:
年月日{
【摘要】:
当前,数字图像技术的主要研究热点之一是数字水印的应用。
本文介绍了LSB算法的思想,利用 VC技术对数字图像水印LSB算法进行实现,并总结LSB算法的利弊,提出了可行的改进措施。
》
关键词:VC;图像处理;数字水印;LSB算法
#
一、前言 (9)
背景 (9)
/
数字水印的现状 (10)
数字水印的应用 (12)
二、数字水印技术 (14)
数字水印的起源、概念和基本原理 (14)
数字水印的嵌入和提取 (14)
三、数字水印的典型算法 (15)
最低有效位算法(LSB) (16)
Patchwork 算法 (16)
<
纹理块映射编码 (16)
其他 (16)
四、LSB算法的VC实现 (16)
五、实验体会 (20)
参考书目: (21)
附录1:算法设计说明书 (21)
附录二:主要原程序 (23)
&
*
]
一、前言
)
背景
随着网络通信的普及,许多传统媒体内容都向数字化转变,并且在电子商务中即将占据巨大的市场份额,如mP3的网上销售,数字影院的大力推行,网上图片、电子书籍销售等等。
在无线领域,随着移动网络由第二代到第三代的演变,移动用户将能方便快速的访问因特网上数字媒体内容,基于有线或无线网络的数字媒体内容的影院即将是信息时代新的趋势。
但是,数字媒体内容的安全问题恰恰制约着信息化进程,虽然成熟的密码学可以解决安全传递和访问控制,但是一旦解密后,数字媒体内容便可以随意的被拷贝、传播,它给媒体内容制造商造成了巨大的损失;同时,密文信息的传递也容易引起攻击者的注意。
因此如何安全的传送信息就成了其中的关键,数字水印技术就成为开启这一难点的钥匙。
数字水印(digital water marking)是实现版权保护的有效办法,已成为多媒体信息安全研究领域的一个热点,也是信息隐藏技术研究领域的重要分支。
它通过在原始数据中嵌入秘密信息—水印(water mark)来证实该数据的所有权。
被嵌入的水印可以是一段文字、标识、序列号等。
水印通常是不可见的或不可察的,它与原始数据(如图像、音频、视频数据等)紧密结合并隐藏其中,成为源数据不可分离的一部分,并可以经历一些不破坏源数据使用价值或商用价值的操作而存活下来。
数字水印技术除具备信息隐藏技术的一般特点外,还有着其固有的特点和研究方法。
例如,从信息安全的保密角度而言,隐藏的信息如果被破坏掉,系统可以视为安全的,因为秘密信息并未泄露;但是,在数字水印系统中,隐藏信息的丢失意味着版权信息的丢失,从而失去了版权保护的功能,这一系统就是失败的。
因此数字水印技术必须具有以下特性:安全性(嵌入在宿主数据中的水印是不可删除的,且能够提供完全的版权证据)、鲁棒性(水印对有意或无意的图像操作与失真具有一定的抵抗力)以及不可觉察性(水印对人的感觉器官应是不可觉察的,或者说是透明的)。
水印算法识别被嵌入到保护对象中的所有者的有关信息(如注册的用户号码、产品标志或有意义的文字等),并能在需要的时候将其提取出来。
水印可以用来判别对象是否受到保护,并能够监视被保护数据的传播、真伪鉴别
以及非法拷贝控制等,这实际上是发展数字水印的基本动力。
尽管版权保护是发展数字水印最重要的源动力,事实上人们还发现数字水印在真伪鉴别、隐藏通信、篡改提示、使用控制、标题与注释等领域都有重要应用。
数字水印术与古老的信息隐藏和数据加密技术关系非常密切,这些技术的发展以及融合为今后信息技术的发展提供必不可少的安全手段。
数字水印的现状
自从第一篇在主要会议上发表的关于数字水印的文章,即VanSchyndel在xexP’94上发表的题为“Adigitalwatermark”的文章]1[以来,对数字水印的研究兴趣在不断的增长。
这既可以从学术界也可以从工业界看出来。
学术界的热情反映在水印方面的文章还在大幅度增长,且有关数字水印和数据隐藏的会议也增长很快,几个有影响的国际会议(如IEEE ICIP、IEEE ICASSP、ACM Multimedia 等)以及一些国际权威杂志(如Proceedings of IEEE Signal processing,IEEE Journal of Selected Areas on Communication,Communications of ACM等)相继出版了数字水印的专辑。
并且,国际上还成立了一些专门的研究机构,如拷贝保护技术工作组(CPTWG,Copy protection Technique Working Group)从1995年开始致力于基于DVD的视频版权保护研究,安全数字音乐创始(SDMI,Secure Digital Music Initiative)从1999年开始研究音频的版权保护,数字水印就是其中的核心关键技术。
一项由德国人开发出来的数字水印技术已经在比利时开始商业应用,这项技术据称可以防止在线音乐的非法复制。
首个应用该技术的是比利时歌手SoulBob 的新专辑,该专辑将很快可以在网络上下载。
不过购买者的姓名以及住址等个人信息将加入到数字水印中。
这样非法复制的音乐将可以很快找到源头。
目前国际上的剑桥大学、IBM研究中心、NEC美国研究所、麻省理工学院等都进行了广泛深入的研究;国际标准组织也对数字水印技术深感兴趣。
如欧洲的TALISMAN的目标是建立一个在欧洲范围内对大规模的商业侵权和盗版行为提供一个版权保护机制。
TALIMAN希望能够为视频产品以增加标识和水印的
方法提高保护手段。
OCEAUS则是TALIMAN和OKAPI的后续项目,其主要目的是将有条件的访问机制和版权保护机制整合起来。
即将发布的数字视频压缩标
准MPEG-4,提供一个框架允许结合简单的加密方法和水印嵌入方法。
DVD工业标准将利用水印技术提供复制控制和复制保护机制,如“复制一次”或“不允许复制”等等。
)
我国学术界对数字水印技术的研究也方兴未艾,已经有相当一批有实力的科研机构投入到这一领域的研究中来,有的已经取得了重要研究成果。
为推动我国在数字水印这一国际前沿计算机技术的发展,促进我国研究人员在此领域的交流与合作,国家863计划智能计算机专家,会同中科院自动化所模式识别国家重点实验室和北京邮电大学信息安全中心,于2000年年初召开了国内首次数字水印学术研讨会。
来自全国20多家重点高校和科研单位计算机、自动化、电子学科及数学学科的80多名科研一线专家与青年工作者,参加了这次研讨会。
众多的学术成果表明,我国科研工作者在数字水印方面的研究处于国际先进水平。
同时,他们表示要尽快把研究成果转化为生产力,解决与每个人切身利益密切相关的数字产品保护问题。
但是,我国在该领域的研究尚不普及,随着数字化产品在中国的广泛开展,特别是今后几年因特网用户将成倍增长,电子商务会加速发展,在网络上直接销售数字化产品将给厂家带来极大的商机,也是中国产品走向世界的极佳途径,其时如何有效保护产品的产权将成为厂商极为关心的问题。
到目前为止,数字水印从研究对象上看主要涉及图像水印]63,2[-、视频水印
[-等几个方面,其中大
12
7[-、音频水印]11,10[、文本水印]2[和三维网格数据水印]15
]9
部分的水印研究和论文都集中在图像研究上,其原因在于图像是最基本的多媒体数据,且互联网的发展为图像水印的应用提供了直接大量的应用需求。
另外视频水印也吸引了一些研究人员,由于视频可以看成时一空域上的连续图像序列,从某种意义上讲,它与图像水印的原理非常类似,许多图像水印的研究结果可以直接应用于视频水印上。
但两者有一个重要的差别在于处理信号的数量级上,特别是视频水印需要考虑实时性问题。
数字水印的应用
数字水印的应用研究成为了国内外公司和学术界的研究焦点。
大部分的工作致力于寻求同时满足保真度、鲁棒性、嵌入容量和经济约束的平衡点。
针对几何和时间上失真的研究,也有稳步进展,出现了大量不同变换域的实验结果,如频域变换有DCT,FFT,DWT和Fourier-Mellin等算法,还有大量的算法在MPEG 和JPEG编码中进行,因为这样可以节省昂贵的水印解码负荷,有利于大批量的应用,如DVD拷贝控制应用等.目前数字水印的应用主要集中在以下几个方面:
1) 版权保护版权标识水印是目前研究最多的一类数字水印。
由于数字作品的拷贝、修改非常容易,而且可以做到与原作完全相同,所以原创者不得不采用一些严重损害作品质量的办法来加上版权标志,而这种明显可见的标志很容易被篡改。
数字作品的所有者可用密钥产生一个水印,并将其嵌入原始数据,然后公开发布其水印版本作品。
当该作品被盗版或出现版权纠纷时,所有者即可从盗版作品或水印版作品中获取水印信号作为依据,从而保护所有者的权益。
2) 加指纹如果嵌入到数字媒体中的数字水印用以标一记媒体的使用者,当出现侵权行为时,通过检测水印信息便可跟踪盗版。
此时数字水印称之为数字指纹。
它要求水印信息具有很高的高鲁棒性、高容量。
为避免未经授权的拷贝制作和发行,出品人可以将不同用户的ID或序列号作为数字指纹嵌入作品的合法拷贝中。
一旦发现未经授权的拷贝,就可以根据此拷贝所恢复出的指纹来确定它的来源。
美国TTR公司用DiscGuard防盗版技术来保护软件出版商的知识产权、防止软件被盗版或非法复制。
这种技术在CD一ROM和DVD盘片上嵌入一个不可复制的“数字指纹,利用这个“数字指纹”可以鉴别出光盘是正版还是盗版,从而控制软件的运行,即有“指纹”才能运行,没“指纹”不能运行。
这个“数字指纹”是在母版制作(Mastering)过程中,通过在现有母版制作的激光系统上加入一个插件或者通过增强型光盘刻录机实现的。
用这个刻有“数字指纹”的母版复制出的每一张CD一ROM都含有“数字指纹,这个“数字指纹,不能够再被复制的。
无论是利用光盘刻录机或者用这张CD一ROM再做母版,都不能复制“数字指纹”,也就是非法复制的CD一ROM不含“数字指纹”,盗版的软件不能运行,从而保护了软件开发者的知识产权。
^
3) 标题与注释即将作品的标题、注释等内容(如,一幅照片的拍摄时间和地点等)以水印形式嵌入该作品中,这种隐式注释不需要额外的带宽,且不易丢失。
4) 篡改提示当数字作品被用于法庭、医学、新闻及商业时,常需确定它们的内容是否被修改、伪造或特殊处理过。
为实现该目的,通常可将原始图像分成多个立块,再将每个块加入不同的水印。
同时可通过检测每个数据块中的水印信号,来确定作品的完整性。
与其他水印不同的是,这类水印必须是脆弱的,并且检测水印信号时,不需要原始数据。
5) 使用控制这种应用的一个典型的例子是DVD 防拷贝系统,即将水印信息加入OVO数据中,这样OVO播放机即可通过检测OVO数据中的水印信息而判断其合法性和可拷贝性。
从而保护制造商的商业利益。
6)内容认证如果数字水印不具有鲁棒性,则当数字媒体受到处理时,嵌入到其中的水印信息不可避免被破坏;根据水印被破坏的情况可以对数字媒体进行内容认证。
此时,数字水印具有易碎性(或是半易碎性):对改变媒体内容的处理不具有任何鲁棒性,对不改变媒体内容的处理具有一定的鲁棒性,在此方面优于数字签名技术。
这方面的研究已经有很长时间了,并且己经取得了丰硕的成果。
目前主要分为可逆数字水印和不可逆数字水印。
7)隐蔽通信及其对抗数字水印所依赖的信息隐藏技术不仅提供了非密码的安全途径,可以实现网络情报战的革命。
网络情报战是信息战的重要组成部分,其核心内容是利用公用网络进行保密数据传送。
由于经过加密的文件往往是混乱无序的,容易引起攻击者的注意。
网络多媒体技术的广泛应用使得利用公用网络进行保密通信有了新的思路,利用数字化声像信号相对于人的视觉、听觉冗余,可以进行各种信息隐藏,从而实现隐蔽通信。
二、数字水印技术
数字水印的起源、概念和基本原理
信息隐藏,也称为信息伪装(StegaflograPhy),该单词来源于古希腊,意思是将有用或重要的信息隐藏于其他信息里面以掩饰其存在,也就是将机密信息秘密地隐藏于另一非机密的文件内容之中。
密码学是研究如何保护消息内容的,而
伪装术(密写术)是专门研究如何隐藏它们的存在性。
《
数字水印技术的基本思想源于古代的伪装术,古希腊的斯巴达人曾将军事情报刻在普通的木板上,用石蜡填平,收信的一方只要用火烤热木板,融化石蜡后就可以看到密信。
使用最广泛的密写方法恐怕要算化学密写了,牛奶、白矾、果汁等都曾充当过密写药水的角色。
大约700年前,在手工造纸技术中出现了纸张上的水印。
数字水印的嵌入和提取
数字水印是向多媒体数据中添加某些数字信息以达到文件真伪鉴别、版权保护等功能。
嵌入的水印信息隐藏于宿主文件中,不影响原始文件的可观性和完整性。
数字图像水印处理过程主要包括水印生成、嵌入和检测三个步骤。
而整个水印系统还应包括外界的攻击过程。
整个数字图像水印系统的基本模型如图1所示。
数字水印生成过程G的输入为原始信息m、原始图像X和水印生成密钥K1,输出为待嵌入的数字水印W。
人们通常采用的水印形式是二进制序列。
有时,数字水印并不通过生成算法生成,而直接给定有意义的图形或图标作为数字水印。
在水印嵌入过程中,原始图像X、水印W以及嵌入密钥K2经过嵌入函数E的作用,生成含水印图像Y。
通常,嵌入函数E用插入操作符作用在一组特
征集F(X)来描述:F(Y)=F(X)W。
根据水印所嵌入的特征集类型的不同,数字图像水印算法一般分为空域算法和变换域算法两类。
另外,一旦生成含水印图像,该图像将在一定的媒介中传输或流通,一定会受到一些有意或无意的攻击,从而得到可疑图像X',关于水印检测,把根据检测密钥K3(有时还需要原始图像X和原始水印W)判断可疑图像X'是否存在水印的过程称为水印检测,而把根据提取密钥 K3提取可疑图像X'中的水印的过程称为水印提取。
三、数字水印的典型算法
数字水印技术横跨了信号处理、数字通信、密码学、模式识别等多种学科,各专业领域的研究者均有独特的研究角度,其算法可谓是五花八门,无所不用,主要的有以下几种:
最低有效位算法(LSB)
(
最低有效位算法(LSB)是和 Schyndel 等人提出的第一个数字水印算法,是一种典型的空间域信息隐藏算法。
LSB 算法使用特定的密钥通过m序列发生器产生随机信号,然后按一定的规则排列成 2 维水印信号,并逐一插入到原始图像相应像素值的最低几位。
由于水印信号隐藏在最低位,相当于叠加了一个能量微弱的信号,因而在视觉和听觉上很难察觉。
LSB 水印的检测是通过待测图像与水印图像的相关运算和统计决策实现的。
Stego Dos 、White Noise Storm 、STools 等早期数字水印算法都采用了 LSB 算法。
LSB 算法虽然可以隐藏较多的信息,但隐藏的信息可以被轻易移去,无法满足数字水印的鲁棒性要求,因此现在的数字水印软件已经很少采用LSB 算法了。
不过,作为一种大数据量的信息隐藏方法, LSB 在隐蔽通信中仍占据着相当重要的地位。
本次实验我所采用就是LSB算法。
Patchwork 算法
Patchwork 是麻省理工学院媒体实验室 Walter Bander 等人提出的一种数
字水印算法,主要用于打印票据的防伪。
Patchwork 数字水印隐藏在特定图像区域的统计特性中,其鲁棒性很强,可以有效地抵御剪切、灰度校正、有损压缩等攻击,其缺陷是数据量较低,对仿射变换敏感,对多拷贝平均攻击的抵抗力较弱。
纹理块映射编码
纹理块映射将水印信息隐藏在图像的随机纹理区域中,利用纹理间的相似性掩盖水印信息。
该算法对滤波、压缩和扭转等操作具有抵抗能力,但需要人工干预。
其他
文本微调算法、DCT 变换域数字水印算法、直接序列扩频水印算法等 】
四、LSB 算法的VC 实现
LSB(最低有效位)算法是一种典型的空间域数据隐藏方法,该方法将特定的标记隐藏于数字音频和数字图像内 。
在灰度图像中,每个像素通常为8位 ,每一位的取值为0或1。
在数字图像中,每个像素的各个位对图像的贡献是不同
的 。
对于8位的灰度图像每个像素的数据g 可用公式表示为 :
∑==7
02i i
i b g 式
中:i 表示像素的第几位;i b 表示第i 位的取值,i b
∈{0,1}。
这样,便可以把整个图像分解为8个位平面,从LSB (最低有效位 )MSB(最高有效位 )。
从位平面的分布来看 ,随着位平面从低位到高(即 从位平面0到位平面 7),位平面图像的特征逐渐变得复杂 ,细节不断增加。
到了比较低的位平面时,单纯从一 幅位平面上已经逐渐不能看出和测试图像的信息了。
由于低位所代表的能量很少, 改变低位对图像的质量没有太大的影响。
LSB 方法正是利用这一点在图像低位隐藏水印信息。
水印嵌入算法:
本文采用VC 技术来开发实现。
所用的嵌入与提取密钥将明文逐位转换成密
文,它是将密钥流Ki与明文流Pi进行异或运算产生密文比特流;Ci=Pi⊕Ki ;在解密端,密文流与完全相同的密钥流异或运算恢复出明文流:Pi=Ci⊕Ki 遮掩消息的LSB 直接被待隐消息的比特位或两者之间经过某种逻辑运算的结果所代替,在此用的是异或运算。
$
主要代码如下:
void
CDib::Embed()字图像的水印技术.上海交通大学学报,2001
附录1:算法设计说明书
数字水印是向多媒体数据中添加某些数字信息以达到文件真伪鉴别、版权保护等功能。
嵌入的水印信息隐藏于宿主文件中,不影响原始文件的可观性和完整性。
数字图像水印处理过程主要包括水印生成、嵌入和检测三个步骤。
而整个
水印系统还应包括外界的攻击过程。
整个数字图像水印系统的基本模型如图1所示。
数字水印生成过程G的输入为原始信息m、原始图像X和水印生成密钥K1,输出为待嵌入的数字水印W。
人们通常采用的水印形式是二进制序列。
有时,数字水印并不通过生成算法生成,而直接给定有意义的图形或图标作为数字水印。
在水印嵌入过程中,原始图像X、水印W以及嵌入密钥K2经过嵌入函数E的作用,生成含水印图像Y。
通常,嵌入函数E用插入操作符作用在一组特征集F(X)来描述:F(Y)=F(X)W。
根据水印所嵌入的特征集类型的不同,数字图像水印算法一般分为空域算法和变换域算法两类。
另外,一旦生成含水印图像,该图像将在一定的媒介中传输或流通,一定会受到一些有意或无意的攻击,从而得到可疑图像X',关于水印检测,把根据检测密钥K3(有时还需要原始图像X和原始水印W)判断可疑图像X'是否存在水印的过程称为水印检测,而把根据提取密钥 K3提取可疑图像X'中的水印的过程称为水印提取。
·
LSB(最低有效位)算法是一种典型的空间域数据隐藏方法,该方法将特定的标记隐藏于数字音频和数字图像内。
在灰度图像中,每个像素通常为8位,
每一位的取值为0或1。
在数字图像中,每个像素的各个位对图像的贡献是不同
的 。
对于8位的灰度图像每个像素的数据g 可用公式表示为 :
∑==7
02i i
i b g 式
中:i 表示像素的第几位;i b 表示第i 位的取值,i b
∈{0,1}。
这样,便可以把整个图像分解为8个位平面,从LSB (最低有效位 )MSB(最高有效位 )。
从位平面的分布来看 ,随着位平面从低位到高(即 从位平面0到位平面 7),位平面图像的特征逐渐变得复杂 ,细节不断增加。
到了比较低的位平面时,单纯从一 幅位平面上已经逐渐不能看出和测试图像的信息了。
由于低位所代表的能量很少, 改变低位对图像的质量没有太大的影响。
LSB 方法正是利用这一点在图像低位隐藏水印信息。
本文采用VC 技术来开发实现。
所用的嵌入与提取密钥将明文逐位转换成密文,它是将密钥流Ki 与明文流Pi 进行异或运算产生密文比特流;Ci =Pi ⊕Ki ;在解密端 ,密文流与完全相同的密钥流异或运算恢复出明文流:Pi =Ci ⊕Ki 遮掩消息的LSB 直接被待隐消息的比特位或两者之间经过某种逻辑运算的结果所代替 ,在此用的是异或运算。
附录二:主要原程序
eRed = m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen = , m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue = m_pPalette[i].rgbBlue;
}
( pLogPal );
delete [] pLogPal; }
《
}
m_BitCount = 24; //24位位图
p = m_pDibBits; //指向位图数据的指针,用来执行处理操作用
bitmap_size = m_dwDibSize - (m_pDibBits - m_pDib);//真正的位图数据的大小(即
除头结构外)
tag = ;
return( TRUE );
>
}
BOOL CDib::Save( const char *pszFilename ) //保存含有隐藏信息的bmp
{
if( m_pDib == NULL )
~
return( FALSE );
CFile cf;
if( !( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );
,
try{
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
= 'MB';
\
= sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
= sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD );
if (embfile_size <= 65535) //由于bfReserved1是unsigned short型的,大小可能不能满足要求,可能要用到reserved2
= embfile_size;
else
]
{
= embfile_size - 65535;
= 1; //标记
}
( &BFH, sizeof( BITMAPFILEHEADER ) );
( m_pDib, m_dwDibSize );
}
}
catch( CFileException *e ){
e->Delete();
return( FALSE );
}
|
return( TRUE );
}
BOOL CDib::Draw( CDC *pDC, int nX, int nY, int nWidth, int nHeight, int Style ) {
if( m_pDib == NULL )
|
return( FALSE );
long vWidth = m_pBIH->biWidth;
if( nWidth == -1 )
nWidth = m_pBIH->biWidth;
if( nHeight == -1 )
、
nHeight = m_pBIH->biHeight;
if (Style)
{
StretchDIBits( pDC->m_hDC, nX, nY,
nWidth, nHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
—
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY );
}
else
{
SetDIBitsToDevice( pDC->m_hDC, nX, nY,
m_pBIH->biWidth, m_pBIH->biHeight,
)
0, 0,
0, m_pBIH->biHeight,
m_pDibBits,
(BITMAPINFO *) m_pBIH,
BI_RGB);
}
return( TRUE );
$
}
BOOL CDib::LoadEmbFile(const char * pszFilename)
{
CFile cf;
~
if( !( pszFilename, CFile::modeRead ) )
return( FALSE );
DWORD dwFileSize;
dwFileSize = ();
embfile_size = dwFileSize;
unsigned char *pFile;
'
pFile = new unsigned char [dwFileSize];
( pFile, dwFileSize ); //将文件中内容读入数组,解下来就开始嵌入操作
m_pFile = pFile;
q = pFile; //记录下位置
return true;
}
;
void CDib::Embed()//嵌入
{
unsigned char bmdata;//bitmap data
unsigned char efdata;//embeddedfile data
int t = 7;
int x[8];
int s[8];
int last_bit; //记录字节最低位本来的bit
—
for(UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++) {
bmdata = *p;
for (int j = 0; j <= 7; j++) //计算各bit位
{
x[j] = bmdata & 1;
;
bmdata >>= 1;
}
last_bit = x[0];
x[0] = x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
if (t == 7) //宿主图片每走过八个字节,计算一次s[]
{
,
efdata = *q;
for (j = 0; j <= 7; j++)
{
s[j] = efdata & 1;
efdata >>= 1;
}
}
x[0] ^= s[t];//隐藏信息
<
if (last_bit == 0) //嵌入隐藏信息
{
*p |= x[0];
}
else
{
*p &= 254 + x[0];
}
p++;
t--;
if (t == -1) //需要计算一次s[]
{
t = 7;
q++;
i2++;
.
}
}
}
void CDib::Pick()//提取
{
m_pFile = new unsigned char [embfile_size];
"
unsigned char *q = m_pFile;
unsigned char bmdata;//bitmap data
int x[8];
int s[8];
int t = 7;
for (UINT i1 = 0, i2 = 0; i1 <= bitmap_size - 1, i2 <= embfile_size - 1; i1++)、
{
bmdata = *p;
for (int j = 0; j <= 7; j++) //计算各bit位
{
x[j] = bmdata & 1;
bmdata >>= 1;
}
s[t] = x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7];
;
t--;
if (t == -1) //s[7]到s[0]组成一个字节
{
*q = s[7] * 128 + s[6] * 64 + s[5] * 32 + s[4] * 16 +
s[3] * 8 + s[2] * 4 + s[1] * 2 + s[0];
t = 7;
i2++;
q++;
}
p++;
}
}
void CDib::SavePicked( const char *pszFilename )
{
!
CFile cf;
( pszFilename, CFile::modeCreate | CFile::modeWrite );
( m_pFile, embfile_size );
}
void CDib::BackUpDib()
{
《
m_pOldDibShow = new unsigned char [bitmap_size];
::CopyMemory(m_pOldDibShow, m_pDibBits, bitmap_size); //将原始的数据单独保存以便对比显示
}
BOOL CDib::DrawContrast(CDC *pDC, int rect_width, int rect_height)
{ //看原图,如果容纳得下两个图,则不要压缩,否则要压缩
if (m_pOldDibShow == NULL)
return FALSE;
if (rect_width >= 2*m_pBIH->biWidth + 30 && rect_height >= m_pBIH->biHeight) {
StretchDIBits( pDC->m_hDC, 0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pOldDibShow,
(BITMAPINFO *) m_pBIH,
BI_RGB, SRCCOPY ); // 原图
StretchDIBits( pDC->m_hDC, m_pBIH->biWidth+30, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
0, 0,
m_pBIH->biWidth, m_pBIH->biHeight,
m_pDibBits,。