参考别人的LSB的程序,我只是简单的修改了一下,使得可以从最低位到最高位都可以嵌入数据。
- // LsbT.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include"ED.h"
- #include<iostream>
- using namespace std;
- //#include"ft_dib.cpp"
- int main(int argc,char *argv[])
- {
- int id = -1;
- int b;
- char*filename = new char;
- FTDib dib;
- cout<<"=========基于LSB加密==========="<<endl;
- while(id){
- cout<<"+------------------------------+"<<endl;
- cout<<"| 1.加密一个文件 |"<<endl;
- cout<<"| 2.解密一个BMP文件 |"<<endl;
- cout<<"| 3.退出 |"<<endl;
- cout<<"+------------------------------+"<<endl<<endl;
- cout<<">>>>>>>>>>文件名带后缀<<<<<<<<<<"<<endl<<endl;
- cout<<"请选择:"<<endl;
- cout<<" --->";
- cin>>id;
- switch(id)
- {
- case 1:
- cout<<"原始BMP文件名称:";
- cin>>filename;
- dib.LoadFile(filename);
- /////////////////////////////////
- cout<<"请输入要加密的比特位数: ";
- cin>>b;
- ////////////////////////////////
- cout<<"请输入要加密的文件名称:";
- cin>>filename;
- if(dib.LSBCoder(filename,b)==-1)
- {
- cout<<" >>>文件长度过长<<<"<<endl;
- cout<<"+------------------------------+"<<endl;
- cout<<"| >>>请注意<<< |"<<endl;
- cout<<"| 请隐藏较小文件 |"<<endl;
- cout<<"| 或重新载入较大的bmp文件 |"<<endl;
- cout<<"+------------------------------+"<<endl<<endl;
- cout<<">>>按回车继续操作<<<"<<endl;
- system("pause");
- id = -1;
- break;
- }
- cout<<"加密后BMP文件名称:";
- cin>>filename;
- dib.SaveFile(filename);
- break;
- case 2:
- cout<<"请输入要解密BMP图像名称:";
- cin>>filename;
- dib.LoadFile(filename);
- /////////////////////////////////
- cout<<"请输入要解密的比特位数: ";
- cin>>b;
- ////////////////////////////////
- cout<<"解密后结果文件名称:";
- cin>>filena
- /*********************************************
- * 功能:处理bmp图象
- * 作者:foxtail
- * 构建日期: 2008/3/4
- * 修改作者:erlingmusan
- * 构建日期: 2012/4/13
- *********************************************/
- #include "stdafx.h"
- #include<string>
- #include<fstream>
- #include<iostream>
- #include"ED.h"
- #define BI_RLE8 1L
- #define BI_RLE4 2L
- #define WIDTHBYTES(bits) (((bits)+31)/32*4)
- FTDib::FTDib()
- {
- size = 0;
- pDib = NULL;
- m_pBitmapFileHeader = new BitmapFileHeader;//文件头
- m_pBitmapInfoHeader = new BitmapInfoHeader;//信息头
- m_pBitmapInfo = (BitmapInfo*)m_pBitmapInfoHeader;
- }
- FTDib::~FTDib()
- {
- delete m_pBitmapFileHeader;
- delete m_pBitmapInfoHeader;
- if(pDib)
- {
- delete pDib;
- }
- }
- //---------------------------------------------
- // 载入图像到一片内存区
- //---------------------------------------------
- void FTDib::LoadFile(const char* dibFileName)
- {
- strcpy(m_fileName,dibFileName);
- ifstream dibFile;
- dibFile.open(m_fileName, ios::binary | ios::in);
- dibFile.read((char*)m_pBitmapFileHeader,sizeof(BitmapFileHeader));//读入文件头
- cout<<"读入文件头完毕"<<endl;
- dibFile.read((char*)m_pBitmapInfoHeader,sizeof(BitmapInfoHeader));
- cout<<"读入信息头完毕"<<endl;
- if(m_pBitmapFileHeader->bfType == 0x4d42)
- {
- //读入图像信息
- size = m_pBitmapFileHeader->bfSize - sizeof(BitmapFileHeader) - sizeof(BitmapInfoHeader);
- pDib = new BYTE[size];
- dibFile.read((char*)pDib,size);
- dibFile.close();
- m_pRGB = (RGB_Element*)(pDib);
- m_numberOfColors = GetNumberOfColors();
- if(m_pBitmapInfoHeader->biColors != 0){m_pBitmapInfoHeader->biColors = m_numberOfColors;}
- DWORD colorTableSize = m_numberOfColors * sizeof(RGB_Element);
- m_pData = pDib + colorTableSize;
- if(m_pRGB == (RGB_Element*)m_pData)//没有颜色表
- {
- m_pRGB = NULL;
- }
- m_pBitmapInfoHeader->biDataSize = GetSize();
- m_valid = true;
- cout<<"载入成功"<<endl;
- }
- else
- {
- m_valid = false;
- cerr<<"该图不是bmp格式";
- }
- }
- //---------------------------------------------
- // 检查图片格式
- //---------------------------------------------
- bool FTDib::IsValid()
- {
- return m_valid;
- }
- //---------------------------------------------
- // 取得图片名称或路径
- //---------------------------------------------
- char * FTDib::GetFileName()
- {
- return m_fileName;
- }
- //---------------------------------------------
- // 取得图像宽度和高度
- //---------------------------------------------
- unsigned int FTDib::GetWidth()
- {
- return (unsigned int)m_pBitmapInfoHeader->biWidth;
- }
- unsigned int FTDib::GetHeight()
- {
- return (unsigned int)m_pBitmapInfoHeader->biHeight;
- }
- //---------------------------------------------
- // 取得图像数据区大小
- //---------------------------------------------
- DWORD FTDib::GetSize()
- {
- if(m_pBitmapInfoHeader->biDataSize != 0)
- {
- return m_pBitmapInfoHeader->biDataSize;
- }
- else
- {
- DWORD height = (DWORD)GetHeight();
- DWORD width = (DWORD)GetWidth();
- return height * width;
- }
- }
- //---------------------------------------------
- // 取得图像宽度
- //---------------------------------------------
- DWORD FTDib::GetDibWidthBytes()
- {
- byBitCount = m_pBitmapInfoHeader->biBitPerPixel;
- long nWidth = m_pBitmapInfoHeader->biWidth;
- dwWidthBytes = (DWORD)m_pBitmapInfoHeader->biWidth;
- switch(dwWidthBytes)
- {
- case 1:
- dwWidthBytes = (nWidth + 7)/8;
- case 2:
- dwWidthBytes = (nWidth + 1)/2;
- case 24:
- dwWidthBytes = 3*nWidth;
- }
- while((dwWidthBytes&3) != 0){++dwWidthBytes;}
- return dwWidthBytes;
- }
- //---------------------------------------------
- // 取得图像颜色数
- //---------------------------------------------
- unsigned int FTDib::GetNumberOfColors()
- {
- int numberOfColors;
- if((m_pBitmapInfoHeader->biColors == 0)&&(m_pBitmapInfoHeader->biBitPerPixel < 9))
- {
- switch(m_pBitmapInfoHeader->biBitPerPixel)
- {
- case 1:
- numberOfColors = 2;break;
- case 4:
- numberOfColors = 16;break;
- case 8:
- numberOfColors = 256;
- }
- }
- else
- {
- numberOfColors = (int)m_pBitmapInfoHeader->biColors;
- }
- return numberOfColors;
- }
- //---------------------------------------------
- // 取得图像数据区指针
- //---------------------------------------------
- BYTE *FTDib::GetData()
- {
- return m_pData;
- }
- BYTE *FTDib::GetData2()
- {
- if(GetRGB())
- {
- m_pData2 = m_pData;
- }
- return m_pData2;
- }
- //---------------------------------------------
- // 取得图像颜色表指针
- //---------------------------------------------
- RGB_Element * FTDib::GetRGB()
- {
- return m_pRGB;
- }
- //---------------------------------------------
- // 取得图像信息指针
- //---------------------------------------------
- BitmapInfo * FTDib::GetInfo()
- {
- return m_pBitmapInfo;
- }
- //---------------------------------------------
- // 调色板大小
- //---------------------------------------------
- WORD FTDib::PaletteSize(BYTE *lpDib)
- {
- return (DIBNumColors(lpDib) * sizeof(RGB_Element));
- }
- //---------------------------------------------
- // 取得图像颜色数
- //---------------------------------------------
- WORD FTDib::DIBNumColors(BYTE *lpDib)
- {
- WORD wBitCount;
- wBitCount = ((BitmapInfoHeader*)lpDib)->biBitPerPixel;
- switch(wBitCount)
- {
- case 1:
- return 2;
- case 4:
- return 16;
- case 8:
- return 256;
- default:
- return 0;
- }
- }
- //---------------------------------------------
- // 保存文件
- //---------------------------------------------
- void FTDib::SaveFile(const char* filename)
- {
- ofstream dibFile;
- dibFile.open(filename, ios::out | ios::binary);
- dibFile.write((char*)m_pBitmapFileHeader,sizeof(BitmapFileHeader));
- cout<<"写入文件头完毕"<<endl;
- dibFile.write((char*)m_pBitmapInfoHeader,sizeof(BitmapInfoHeader));
- cout<<"写入信息头完毕"<<endl;
- dibFile.write((char*)pDib,size);
- dibFile.close();
- }
- //---------------------------------------------
- // 基于LSB的信息隐藏
- //---------------------------------------------
- int FTDib::LSBCoder(const char* textFileName,int b)
- {
- ifstream textFile;
- textFile.open(textFileName,ios::in | ios::binary);
- textFile.seekg(0,textFile.end);
- DWORD textFileLength = textFile.tellg();
- //判断位图是否够存储隐藏的信息
- DWORD colorTableSize = m_numberOfColors * sizeof(RGB_Element);
- if((size - colorTableSize)<textFileLength*8)
- {
- return -1; //不够隐藏
- }
- BYTE* pTextFile = new BYTE[textFileLength+1];
- cout<<"隐藏时文件长度:"<<textFileLength<<endl;
- textFile.seekg(0,textFile.beg);
- textFile.read((char*)pTextFile,textFileLength);
- textFile.close();
- BYTE textData;
- for(int i=0,k=0; i< textFileLength; ++i)
- {
- for(int j=0; j<8; ++j)
- {
- textData = pTextFile[i]>>j;
- textData = textData&0x01;
- if(textData==0)
- {
- //pDib[k+32] = pDib[k+32]&0xfe;
- E0(&(pDib[k+32]),b);
- }
- else
- {
- //pDib[k+32] = pDib[k+32]|0x01;
- E1(&(pDib[k+32]),b);
- }
- ++k;
- }
- }
- cout<<"信息隐藏完毕"<<endl;
- //在前四个字节中写入text文件数据长度
- DWORD length;
- for(int i=0; i<32; ++i)
- {
- length = textFileLength>>i;
- length = length&0x00000001;
- if(length==0)
- {
- pDib[i] = pDib[i]&0xfe;
- }
- else
- {
- pDib[i] = pDib[i]|0x01;
- }
- }
- return 0;
- }
- //---------------------------------------------
- // 解码基于LSB的信息隐藏
- //---------------------------------------------
- void FTDib::LSBDecoder(const char* textFileName,int b)
- {
- DWORD length = 0x00000000;
- BYTE bit;
- //获取txt文件长度
- for(int i=0; i<32; ++i)
- {
- bit = pDib[i]&0x01;
- if(bit==0)
- {
- length = length&0x7fffffff;
- }
- else
- {
- length = length|0x80000000;
- }
- if (i<31) length = length>>1;
- }
- cout<<"解码时文件长度:"<<length<<endl;
- //开始解码
- BYTE* pTextFile = new BYTE[length];
- BYTE textData;
- for(int i=0,k=0; i<length*8; ++i)
- {
- if(i && i%8==0){++k;}
- //textData = pDib[i+32]&0x01;
- textData = D(&(pDib[i+32]),b);
- if(textData==0)
- {
- pTextFile[k] = pTextFile[k]&0x7f;
- //D0(&(pTextFile[k]),b);
- }
- else
- {
- pTextFile[k] = pTextFile[k]|0x80;
- //D1(&(pTextFile[k]),b);
- }
- if (i%8 != 7) pTextFile[k] = pTextFile[k]>>1;
- }
- cout<<"解码完毕"<<endl;
- ofstream textFile;
- textFile.open(textFileName,ios::out | ios::binary);
- textFile.write((char*)pTextFile,length);
- textFile.close();
- delete pTextFile;
- }
- void FTDib::E0(BYTE* data,int b)
- {
- switch(b)
- {
- case 0: *data&=0xfe;break;
- case 1: *data&=0xfd;break;
- case 2: *data&=0xfb;break;
- case 3: *data&=0xf7;break;
- case 4: *data&=0xef;break;
- case 5: *data&=0xdf;break;
- case 6: *data&=0xbf;break;
- case 7: *data&=0x7f;break;
- }
- //return *data;
- }
- void FTDib::E1(BYTE* data,int b)
- {
- switch(b)
- {
- case 0: *data|=0x01;break;
- case 1: *data|=0x02;break;
- case 2: *data|=0x04;break;
- case 3: *data|=0x08;break;
- case 4: *data|=0x10;break;
- case 5: *data|=0x20;break;
- case 6: *data|=0x40;break;
- case 7: *data|=0x80;break;
- }
- //return *data;
- }
- BYTE FTDib::D(BYTE* data,int b)
- {
- switch(b)
- {
- case 0: *data&=0x01;break;
- case 1: *data&=0x02;break;
- case 2: *data&=0x04;break;
- case 3: *data&=0x08;break;
- case 4: *data&=0x10;break;
- case 5: *data&=0x20;break;
- case 6: *data&=0x40;break;
- case 7: *data&=0x80;break;
- }
- return *data;
- }
- /*
- void FTDib::D1(BYTE* data,int b)
- {
- switch(b)
- {
- case 0: *data|=0x80;break;
- case 1: *data|=0x40;break;
- case 2: *data|=0x20;break;
- case 3: *data|=0x10;break;
- case 4: *data|=0x08;break;
- case 5: *data|=0x04;break;
- case 6: *data|=0x02;break;
- case 7: *data|=0x01;break;
- }
- //return *data;
- }*/
me;
- dib.LSBDecoder(filename,b);
- break;
- case 3:
- id = 0;
- break;
- default:
- cout<<">>>>输入不符合要求<<<<"<<endl;
- }
- }
- system("pause");
- delete filename;
- return 0;
- }
阅读(1673) | 评论(0) | 转发(0) |