计算机与信息学院信息隐藏实验报告专业班级信息安全13-1班学生姓名及学号马骏 2013211869 课程教学班号任课教师郑淑丽实验指导教师郑淑丽实验地点20 ~20 学年第学期实验1 BMP位图信息隐藏一、实验目的学习BMP格式文件,并编程实现对位图文件信息隐藏二、实验要求将TXT文件嵌入BMP 文件中三、问题描述1、BMP位图文件的格式?2、有哪几种方法隐藏信息,分别采用什么样的数据结构3、随机选取如何避免“碰撞”的出现四、算法思想1、BMP位图文件格式0000h~0001h 2字节-------------------------bm的ASC码0002h~0005h 4字节-------------------------文件大小102718字节0006h~0009h 4字节-------------------------全为0000Ah~000Dh 4字节-------------------------偏移量118字节000Eh~0011h 4字节-------------------------位图信息块大小40字节0012h~0015h 4字节-------------------------宽4500016h~0019h 4字节-------------------------高450001Ah~001Bh 2字节-------------------------恒为01h 00h001Ch~001Dh 2字节-------------------------颜色所占二进制位数值04h 00h=4 16色位图001Eh~0021h 4字节-------------------------压缩方式=0无压缩0022h~0025h 4字节-------------------------图像数据区大小102600字节0026h~0029h 4字节-------------------------水平每米多少像素39个002Ah~002Dh 4字节-------------------------垂直每米多少像素39个002Eh~0031h 4字节-------------------------图像所用颜色数=00032h~0035h 4字节-------------------------重要颜色数=00036h~0076h 64字节-------------------------颜色表0077h~1913Dh 102600字节-------------------------图像数据区2、(1)、在图片图像数据区的一个连续的数据区采用整字节替换的方法(2)、在图像数据的最后增加文本信息的字节(3)、顺序选取每个文本信息字节的每一位替换图像数据区的一个连续的数据区每个字节的最后一位。
(4)、顺序选取每个文本信息字节的每一位替换图像数据区随机选取一个字节的最后一位。
(5)、首先对颜色表排序,比对顺序选取每个文本信息字节的每一位与图像数据区的一个连续的数据区每个字节的最后一位,如果不一致则不断选取相近的颜色,直到颜色序号二进制最后一位与文本信息的字节最后一位一致。
(6)首先对颜色表排序,比对顺序选取每个文本信息字节的每一位与图像数据区的随机选取的数据区每个字节的最后一位,如果不一致则不断选取相近的颜色,直到颜色序号二进制最后一位与文本信息的字节最后一位一致。
3、为了避免“碰撞”则隐藏程序和解密程序需要通过一个协议,规定一个像素点只能使用一次,即隐藏时对使用过的像素点做记录,如果像素点使用过,则产生下一个随机数。
五、模块划分const int max=500000;char huancun[max];//从文件中读入的字符char txthuancun[max];//txt 中的字符char writehuancun[max];//可以写进文件中的字符串long int writehuancunnumber=0;//准备写入文件中的个数long int huancunnumber=0;//从文件中读出字符个数long int txthuancunnumber=0;void read(const char* realfile)//读入huancun[]void txtread(const char* realfile)//读入txthuancun[]void write(const char*yasuofile)void deal8bit(char kp)//仅仅是显示二进制文件的函数void easyswitch()//简单的从100开始置换void endswitch()int calculate8bit(char kp,int byte)//返回一个字符第byte位为0 或1 从右往左数int getbegin()//得到偏移量的大小下一个就是数据区的开始即begin的值char chang8bit(char inputtxt,char bmp,int byte)//txt的第byte 被bmp第八位代替从左向右char changelastbyte(char bmpinput,char txt,int byte) //bmp字节的第8位被txt字节的第byte 位代替从左向右void middleswitch()void highswitch() //还没有解决碰撞问题int caculatechar4(char fun[4])//计算4个char的十进制大小权重1 3 2int caculatelastbit4(char zifu)//计算字节的最后四位代表的十进制数char calculateaddlast4bit(char pt,int colornumber)//第一个字符的前四位保留后四位用这个int 改成的二进制替换class color16//16色颜色元{public: char bit4[4];int myposision;int bitnumber;//char bit[4] 10进制int colornumber;//第几个颜色0到15号颜色};class colortable16//16色颜色表{public: colortable16()void setcolortable(char fun[4],int colornumber)void exchange()//排序int getnextcolornumber(char zifu)//得到相近颜色的颜色好int mycolortable16number;color16 mycolortable16[17];};void middlehidepluspower132()void highhidepluspower132()void discodehighhidepluspower132()//解密函数六、测试数据隐藏信息:hello markchalse,this is a secretnumber 6424155please put this in an code小刀司令程序过程:源文件整字节替换顺序字节末位替换随机字节末位替换文件末位增加字节选择相近颜色顺序字节末位替换选择相近颜色随机字节末位替换源文件整字节替换顺序字节末位替换随机字节末位替换文件末位增加字节选择相近颜色顺序字节末位替换选择相近颜色随机字节末位替换程序分析:在整字节替换中得到的图片产生偏移,而直接对字节末位做替换的程序,会使像素点的颜色反差较大,如果是在颜色表选择相近颜色再对字节末位做替换效果较好,但在纯色区域表现不佳。
在图像数据区后增加字节,没有和原图产生差异,但文件的大小有增加,而且是明文容易被发现。
七、源程序(见附录)八、总结此次实验,使我在学习信息隐藏技术原理的基础上,进一步学习了对位图文件的编程。
更加深了我对信息隐藏的理解。
但程序中依然存在着很多不足,希望在以后的学习中加以完善。
Hidemessage1.cpp/*基本要求:txt 嵌入bmp 文件中*/#include<iostream>#include<string>#include<fstream>#include <sstream>#include<math.h>using namespace std;const char* readbmpfile="n666.bmp";const char* writefile="n888.bmp";const char* readtxtfile="n2.txt";const char* writetxtfile="n999.txt";const int max=500000;char huancun[max];//从文件中读入的字符char txthuancun[max];//txt 中的字符char writehuancun[max];//可以写进文件中的字符串long int writehuancunnumber=0;//准备写入文件中的个数long int huancunnumber=0;//从文件中读出字符个数long int txthuancunnumber=0;void read(const char* realfile)//读入huancun[]{huancunnumber=0;ifstream inputfile;inputfile.open(realfile);if(!inputfile){cout<<"no file"<<endl;}char a;while(!inputfile.eof()){a=inputfile.get();huancun[huancunnumber]=a;huancunnumber++;}inputfile.close();}void txtread(const char* realfile)//读入txthuancun[]{txthuancunnumber=0;ifstream inputfile;inputfile.open(realfile);if(!inputfile)cout<<"no file"<<endl;}char a;while(!inputfile.eof()){a=inputfile.get();txthuancun[txthuancunnumber]=a;txthuancunnumber++;}inputfile.close();for(int x=0;x<txthuancunnumber;x++)cout<<txthuancun[x];cout<<endl;}void write(const char*yasuofile){ofstream outputfile;outputfile.open(yasuofile);long int x;for(x=0;x<writehuancunnumber;x++){outputfile<<writehuancun[x];}outputfile.close();}void deal8bit(char kp)//仅仅是显示二进制文件的函数{char n1,n2,n3,n4,n5,n6,n7,n8;char kk;_asm{mov n1,10000000b;mov n2,01000000b;mov n3,00100000b;mov n4,00010000b;mov n5,00001000b;mov n6,00000100b;mov n7,00000010b;mov n8,00000001b;}kk=kp;_asm{and kk,10000000b; }if(kk==n1){cout<<"1";}else cout<<"0";kk=kp;_asm{and kk,01000000b; }if(kk==n2){cout<<"1";}else cout<<"0";kk=kp;_asm{and kk,00100000b; }if(kk==n3){cout<<"1";}else cout<<"0";kk=kp;_asm{and kk,00010000b; }if(kk==n4){cout<<"1";}else cout<<"0";kk=kp;_asm{and kk,00001000b;}if(kk==n5){cout<<"1";}else cout<<"0";kk=kp;_asm{and kk,00000100b;}if(kk==n6){cout<<"1";}else cout<<"0";kk=kp;_asm{and kk,00000010b;}if(kk==n7){cout<<"1";}else cout<<"0";kk=kp;_asm{and kk,00000001b;}if(kk==n8){cout<<"1";}else cout<<"0";};void easyswitch()//简单的从100开始置换{int x;cout<<endl;cout<<"------------------------------easyswitch program-------------------------------"<<endl;writehuancunnumber=huancunnumber;for(x=0;x<huancunnumber;x++)writehuancun[x]=huancun[x];for(x=0;x<txthuancunnumber;x++)writehuancun[x+1500]=txthuancun[x];}void endswitch(){int end=huancunnumber,x;//最后就指数据区的最后cout<<"------------------------------endswitch program-------------------------------"<<endl;writehuancunnumber=huancunnumber;for(x=0;x<huancunnumber;x++)writehuancun[x]=huancun[x];for(x=0;x<txthuancunnumber;x++){writehuancun[writehuancunnumber]=txthuancun[x];writehuancunnumber++;}}int calculate8bit(char kp,int byte)//返回一个字符第byte位为0 或1 从右往左数{char n1,n2,n3,n4,n5,n6,n7,n8;char kk;_asm{mov n1,10000000b;mov n2,01000000b;mov n3,00100000b;mov n4,00010000b;mov n5,00001000b;mov n6,00000100b;mov n7,00000010b;mov n8,00000001b;}if(byte==8){kk=kp;_asm{and kk,10000000b;}if(kk==n1){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}if(byte==7){kk=kp;_asm{and kk,01000000b;}if(kk==n2){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}if(byte==6){kk=kp;_asm{and kk,00100000b;}if(kk==n3){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}if(byte==5){kk=kp;_asm{and kk,00010000b;}if(kk==n4){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}if(byte==4){kk=kp;_asm{and kk,00001000b;}if(kk==n5){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}if(byte==3){kk=kp;_asm{and kk,00000100b;}if(kk==n6){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}if(byte==2){kk=kp;_asm{and kk,00000010b;}if(kk==n7){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}if(byte==1){kk=kp;_asm{and kk,00000001b;}if(kk==n8){// cout<<"1";return 1;}else{// cout<<"0";return 0;}}}int getbegin()//得到偏移量的大小下一个就是数据区的开始即begin的值{int pianyi=0,x;char pianyi1=huancun[10];//从第11个字节开始的四个字节char pianyi2=huancun[11];char pianyi3=huancun[12];char pianyi4=huancun[13];for(x=0;x<8;x++){if(calculate8bit(pianyi1,x+1))//一定要注意:直观上的第8位实际上只是数字的最低位第几位这个是从左往右还是从右往左要一致{int kk=1; //这里按从右往左算没有第0位这个说法所以还要x+1for(int t=0;t<x;t++)//x最大为7 最高位2的7次方没错kk=kk*2;pianyi+=kk;}}for(x=0;x<8;x++){if(calculate8bit(pianyi2,x+1)) //这里按从右往左算没有第0位这个说法所以还要x+1{int kk=1;for(int t=0;t<x+8;t++)kk=kk*2;pianyi+=kk;}}for(x=0;x<8;x++){if(calculate8bit(pianyi3,x+1)) //这里按从右往左算没有第0位这个说法所以还要x+1{int kk=1;for(int t=0;t<x+16;t++)kk=kk*2;pianyi+=kk;}}for(x=0;x<8;x++){if(calculate8bit(pianyi4,x+1)) //这里按从右往左算没有第0位这个说法所以还要x+1{int kk=1;for(int t=0;t<x+24;t++)kk=kk*2;pianyi+=kk;}}return pianyi;}char chang8bit(char inputtxt,char bmp,int byte)//txt的第byte 被bmp第八位代替从左向右{char txt=inputtxt;char n1,n2,n3,n4,n5,n6,n7,n8,ntrue,nfalse;_asm{mov n1,10000000b;mov n2,01000000b;mov n3,00100000b;mov n4,00010000b;mov n5,00001000b;mov n6,00000100b;mov n7,00000010b;mov n8,00000001b;mov ntrue,00000001b;mov nfalse,11111110b;and bmp,00000001;}if(bmp==ntrue){if(byte==1){_asm{or txt,10000000b}}if(byte==2){_asm{or txt,01000000b}}if(byte==3){_asm{or txt,00100000b}}if(byte==4){_asm{or txt,00010000b}}if(byte==5){_asm{or txt,00001000b}}if(byte==6){_asm{or txt,00000100b}}if(byte==7){_asm{or txt,00000010b}}if(byte==8){_asm{or txt,00000001b}}}else{if(byte==1){_asm{and txt,01111111b;}}if(byte==2){_asm{and txt,10111111b;}}if(byte==3){_asm{and txt,11011111b;}}if(byte==4){_asm{and txt,11101111b;}}if(byte==5){_asm{and txt,11110111b;}}if(byte==6){_asm{and txt,11111011b;}}if(byte==7){_asm{and txt,11111101b;}}if(byte==8){_asm{and txt,11111110b;}}}return txt;};char changelastbyte(char bmpinput,char txt,int byte) //bmp字节的第8位被txt字节的第byte 位代替从左向右{char bmp=bmpinput;char n1,n2,n3,n4,n5,n6,n7,n8,ntrue,nfalse;char kk;_asm{mov n1,10000000b;mov n2,01000000b;mov n3,00100000b;mov n4,00010000b;mov n5,00001000b;mov n6,00000100b;mov n7,00000010b;mov n8,00000001b;mov ntrue,00000001b;mov nfalse,11111110b;}if(byte==1){kk=txt;_asm{and kk,10000000b;}if(kk==n1){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}if(byte==2){kk=txt;_asm{and kk,01000000b;}if(kk==n2){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}if(byte==3){kk=txt;_asm{and kk,00100000b;}if(kk==n3){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}if(byte==4){kk=txt;_asm{and kk,00010000b;}if(kk==n4){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}if(byte==5){kk=txt;_asm{and kk,00001000b;}if(kk==n5){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}if(byte==6){kk=txt;_asm{and kk,00000100b;}if(kk==n6){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}if(byte==7){kk=txt;_asm{and kk,00000010b;}if(kk==n7){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}if(byte==8){kk=txt;_asm{and kk,00000001b;}if(kk==n8){// cout<<"1";_asm{or bmp,00000001b;}return bmp;}else{// cout<<"0";_asm{and bmp,11111110b;}return bmp;}}}void middleswitch(){int begin,end=huancunnumber,x,y,i;//最后就指数据区的最后cout<<"------------------------------begin middle switch program-------------------------------"<<endl;begin=getbegin();begin++;// 注意bmp 记录的偏移字节数并不是图像数据区的开始坐标它加1才是!!!!cout<<"begin:"<<begin<<endl;writehuancunnumber=huancunnumber;for(x=0;x<huancunnumber;x++)writehuancun[x]=huancun[x];i=0;for(x=0;x<txthuancunnumber;x++){for(y=1;y<=8;y++){writehuancun[i+begin+1030]=changelastbyte(writehuancun[i+begin+1030],txthuancun[x],y);i++;}}}void highswitch() //还没有解决碰撞问题{int begin,end=huancunnumber,x,y,i;//最后就指数据区的最后cout<<"------------------------------begin high switch program-------------------------------"<<endl;begin=getbegin();begin++;// 注意bmp 记录的偏移字节数并不是图像数据区的开始坐标它加1才是!!!!cout<<"begin:"<<begin<<endl;writehuancunnumber=huancunnumber;for(x=0;x<huancunnumber;x++)writehuancun[x]=huancun[x];i=0;srand(9527);for(x=0;x<txthuancunnumber;x++){for(y=1;y<=8;y++){writehuancun[begin+1030+rand()]=changelastbyte(writehuancun[i+begin+1030],txthuancun[x],y) ;i++;}}srand(9527);cout<<endl<<"hhahahaha"<<rand()<<endl;cout<<endl<<"hhahahaha"<<rand()<<endl;cout<<endl<<"hhahahaha"<<rand()<<endl;srand(27149);cout<<endl<<"hhahahaha"<<rand()<<endl;cout<<endl<<"hhahahaha"<<rand()<<endl;cout<<endl<<"hhahahaha"<<rand()<<endl;srand(9527);cout<<endl<<"hhahahaha"<<rand()<<endl;cout<<endl<<"hhahahaha"<<rand()<<endl;cout<<endl<<"hhahahaha"<<rand()<<endl;};int caculatechar4(char fun[4])//计算4个char的十进制大小权重1 3 2{int x,result=0;//0 1 2 3 9 10 11 为0for(x=1;x<=8;x++){if(calculate8bit(fun[0],x)){int k=1;for(int y=0;y<x-1;y++)k=k*2;result+=k;}}//0 1 4 5 9 12 13 为0for(x=1;x<=8;x++){if(calculate8bit(fun[1],x)){int k=1;for(int y=0;y<x+16-1;y++)k=k*2;result+=k;}}//奇数颜色全为0for(x=1;x<=8;x++){if(calculate8bit(fun[2],x)){int k=1;for(int y=0;y<x+8-1;y++)k=k*2;result+=k;}}/* //最后一个亮度char 竟然全为0for(x=1;x<=8;x++){if(calculate8bit(fun[3],x)){int k=1;for(int y=0;y<x+24-1;y++)k=k*2;result+=k;}}*/return result;};int caculatelastbit4(char zifu)//计算字节的最后四位代表的十进制数{int x,result=0;for(x=1;x<=4;x++){if(calculate8bit(zifu,x)){int k=1;for(int y=1;y<x;y++)k=k*2;result+=k;}}return result;};char calculateaddlast4bit(char pt,int colornumber)//第一个字符的前四位保留后四位用这个int 改成的二进制替换{// or pt,a;//千万记住内联汇编不能用两个变量or 或者and_asm{and pt,11110000b;}if(colornumber==0){_asm{or pt,00000000b;}}if(colornumber==1){_asm{or pt,00000001b;}}if(colornumber==2){_asm{or pt,00000010b;}}if(colornumber==3){_asm{or pt,00000011b;}}if(colornumber==4){_asm{or pt,00000100b;}}if(colornumber==5){_asm{or pt,00000101b;}}if(colornumber==6){_asm{or pt,00000110b;}}if(colornumber==7){_asm{or pt,00000111b;}}if(colornumber==8){_asm{or pt,00001000b;}}if(colornumber==9){_asm{or pt,00001001b;}}if(colornumber==10){_asm{or pt,00001010b;}}if(colornumber==11){_asm{or pt,00001011b;}}if(colornumber==12){_asm{or pt,00001100b;}}if(colornumber==13){_asm{or pt,00001101b;}}if(colornumber==14){_asm{or pt,00001110b;}}if(colornumber==15){_asm{or pt,00001111b;}}return pt;};class color16//16色颜色元{public:char bit4[4];int myposision;int bitnumber;//char bit[4] 10进制int colornumber;//第几个颜色0到15号颜色};class colortable16//16色颜色表{public:colortable16(){mycolortable16number=0;};void setcolortable(char fun[4],int colornumber){for(int x=0;x<4;x++){mycolortable16[mycolortable16number].bit4[x]=fun[x];}mycolortable16[mycolortable16number].bitnumber=caculatechar4(fun);//计算4个char 的十进制大小// mycolortable16[mycolortable16number].myposition=position;mycolortable16[mycolortable16number].colornumber=colornumber;mycolortable16number++;};void exchange()//排序{int x,y;color16 linshicolor;for(x=0;x<mycolortable16number-1;x++){for(y=x+1;y<mycolortable16number;y++){if(mycolortable16[x].bitnumber>mycolortable16[y].bitnumber){linshicolor=mycolortable16[x];mycolortable16[x]=mycolortable16[y];mycolortable16[y]=linshicolor;}}}};/*int getnextposition(char zifu)//得到下一个相邻颜色的颜色表位置{int x,y;y=caculatelastbit4(zifu);//计算字节的最后四位代表的十进制数for(x=0;x<mycolortable16number;x++){if(mycolortable16[x].colornumber==y) return mycolortable16[x+1].myposition;}};*/int getnextcolornumber(char zifu)//得到相近颜色的颜色好{int x,y;y=caculatelastbit4(zifu);//计算字节的最后四位代表的十进制数for(x=0;x<mycolortable16number;x++){if(mycolortable16[x].colornumber==y){cout<<"number:"<<y<<" ";if(x==mycolortable16number-1){return mycolortable16[0].colornumber;}else{cout<<mycolortable16[x+1].colornumber<<" ";return mycolortable16[x+1].colornumber;}}}};int mycolortable16number;color16 mycolortable16[17];};void middlehidepluspower132(){cout<<"-------------------------middle hide plus program------------------"<<endl;//创建图像表、初始化、排序colortable16 mark;char data[4];int begin,end=huancunnumber,x,y,i;//最后就指数据区的最后int start=54;begin=getbegin();begin++;// 注意bmp 记录的偏移字节数并不是图像数据区的开始坐标它加1才是!!!!cout<<"begin:"<<begin<<endl;writehuancunnumber=huancunnumber;for(x=0;x<huancunnumber;x++)writehuancun[x]=huancun[x];for(x=0;x<16;x++){for(y=0;y<4;y++)data[y]=huancun[y+start];mark.setcolortable(data,x);start+=4;}mark.exchange();for(x=0;x<mark.mycolortable16number;x++){cout<<mark.mycolortable16[x].bitnumber<<""<<mark.mycolortable16[x].colornumber<<endl;}//1、提取一个字符8位信息//2、对每一位信息从图像数据区每一字节比对//3、如果一致下一个//4、不一致寻找排序后图像表对应下一个颜色的图像数据区位置(myposition)进行二进制位最后一位比较如果相同则替换,否则循环找下一颜色i=0;for(x=0;x<txthuancunnumber;x++){for(y=1;y<=8;y++){char f=writehuancun[i+begin+1030];while(writehuancun[i+begin+1030]!=changelastbyte(f,txthuancun[x],y)){writehuancun[i+begin+1030]=calculateaddlast4bit(writehuancun[i+begin+1030],mark.getnextcolo rnumber(writehuancun[i+begin+1030]));//第一个字符的前四位保留后四位用这个int 改成的二进制替换f=writehuancun[i+begin+1030];cout<<i<<" ";}i++;}}};void highhidepluspower132(){cout<<"-------------------------high hide plus program------------------"<<endl;unsigned int key=0;while(key<1||key>65534){cout<<"please enter your key 1=<key<=65534 key=";cin>>key;}srand(key);int xiangsutable[10000];//不能用max了太大了程序崩溃了int xiangsutablenumber=0;int check=1;//创建图像表、初始化、排序colortable16 mark;char data[4];int begin,end=huancunnumber,x,y,i;//最后就指数据区的最后int start=54;begin=getbegin();begin++;// 注意bmp 记录的偏移字节数并不是图像数据区的开始坐标它加1才是!!!!cout<<"begin:"<<begin<<endl;writehuancunnumber=huancunnumber;for(x=0;x<huancunnumber;x++)writehuancun[x]=huancun[x];for(x=0;x<16;x++){for(y=0;y<4;y++)data[y]=huancun[y+start];mark.setcolortable(data,x);start+=4;}mark.exchange();for(x=0;x<mark.mycolortable16number;x++){cout<<mark.mycolortable16[x].bitnumber<<""<<mark.mycolortable16[x].colornumber<<endl;}//1、提取一个字符8位信息//2、对每一位信息从图像数据区每一字节比对//3、如果一致下一个//4、不一致寻找排序后图像表对应下一个颜色的图像数据区位置(myposition)进行二进制位最后一位比较如果相同则替换,否则循环找下一颜色while(check){int kk=1;i=rand();i=(double(i)/double(32767))*(double)(end-begin);for(int t=0;t<xiangsutablenumber;t++){if(i==xiangsutable[t]){kk=0;break;}}if(kk){xiangsutable[xiangsutablenumber]=i;xiangsutablenumber++;check=0;}}for(x=0;x<txthuancunnumber;x++){for(y=1;y<=8;y++){char f=writehuancun[i+begin];while(writehuancun[i+begin]!=changelastbyte(f,txthuancun[x],y)){writehuancun[i+begin]=calculateaddlast4bit(writehuancun[i+begin],mark.getnextcolornumber(wri tehuancun[i+begin]));//第一个字符的前四位保留后四位用这个int 改成的二进制替f=writehuancun[i+begin];}cout<<"i:"<<i;cout<<" txt:";deal8bit(txthuancun[x]);cout<<" y:"<<y<<" ";deal8bit(writehuancun[i+begin]);cout<<" ";check=1;while(check){int kk=1;i=rand();i=(double(i)/double(32767))*(double)(end-begin);for(int t=0;t<xiangsutablenumber;t++){if(i==xiangsutable[t]){kk=0;break;}}if(kk){xiangsutable[xiangsutablenumber]=i;xiangsutablenumber++;check=0;}}}}};void discodehighhidepluspower132(){cout<<"-------------------------discode high hide plus program------------------"<<endl;unsigned int key=0;while(key<1||key>65534){cout<<"please enter your key 1=<key<=65534 key=";cin>>key;}srand(key);int xiangsutable[10000];//不能用max了太大了程序崩溃了int xiangsutablenumber=0;int check=1;int begin,end=huancunnumber-1,x,y,i;// 注意重新读取的隐藏后的图片会比原始图像多一字节!!!!原因未知begin=getbegin();begin++;// 注意bmp 记录的偏移字节数并不是图像数据区的开始坐标它加1才是!!!!cout<<"begin:"<<begin<<endl;writehuancunnumber=txthuancunnumber;//这是个bug 由于最初没有把txt的大小写进图片暂定程序记录的字符数可以升级的地方check=1;while(check){int kk=1;i=rand();i=(double(i)/double(32767))*(double)(end-begin);for(int t=0;t<xiangsutablenumber;t++){if(i==xiangsutable[t]){kk=0;break;}}if(kk){xiangsutable[xiangsutablenumber]=i;xiangsutablenumber++;check=0;}}for(x=0;x<writehuancunnumber;x++){for(y=1;y<=8;y++){writehuancun[x]=chang8bit(writehuancun[x],huancun[i+begin],y);cout<<"i:"<<i;cout<<" ";deal8bit(huancun[i+begin]);cout<<"y:"<<y<<" ";deal8bit(writehuancun[x]);check=1;while(check){int kk=1;i=rand();i=(double(i)/double(32767))*(double)(end-begin);for(int t=0;t<xiangsutablenumber;t++){if(i==xiangsutable[t]){kk=0;break;}}if(kk){xiangsutable[xiangsutablenumber]=i;xiangsutablenumber++;check=0;}}}}};int main(){read(readbmpfile);int x;int y=0;for(x=0;x<huancunnumber;x++){deal8bit(huancun[x]);y++;if(y==8){cout<<endl;y=0;}cout<<" ";}cout<<endl;txtread(readtxtfile);int quit=1;while(quit){int a;cout<<"---------------------------------select hide program---------------------------"<<endl<<"0 quit"<<endl<<"1 easy hide program"<<endl<<"2 end hide program"<<endl;cout<<"3 middle hide program"<<endl;cout<<"4 high hide program"<<endl;cout<<"5 middle hide plus program for power 1 3 2"<<endl;cout<<"6 high hide plus program for power 1 3 2"<<endl;cout<<"7 discode high hide plus program for power 1 3 2"<<endl;cin>>a;。