国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

C/C++信息隱寫(xiě)術(shù)(二)之字符串藏入BMP文件

2019-11-14 09:09:05
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

我們這一節(jié)用代碼實(shí)現(xiàn),把字符串藏入BMP文件,并且能正常讀取出來(lái)。

看這篇的同學(xué)請(qǐng)先閱讀第一篇了解理論:

http://blog.csdn.net/QQ78442761/article/details/54863034

下面開(kāi)始進(jìn)入此節(jié):

從上一節(jié),我們知道了Bmp文件的結(jié)構(gòu),如下圖所示:

其中最關(guān)鍵的兩個(gè)結(jié)構(gòu)體BITMAPFILEHEADER和BITMAPINFOHEADER,這里面保存了這個(gè)Bmp文件的很多信息。

恰好,Windows給我們提供了這個(gè)兩個(gè)結(jié)構(gòu)體,如下圖所示:

typedef struct tagBITMAPFILEHEADER {        Word    bfType;        DWORD   bfSize;        WORD    bfReserved1;        WORD    bfReserved2;        DWORD   bfOffBits;} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{        DWORD      biSize;        LONG       biWidth;        LONG       biHeight;        WORD       biplanes;        WORD       biBitCount;        DWORD      biComPRession;        DWORD      biSizeImage;        LONG       biXPelsPerMeter;        LONG       biYPelsPerMeter;        DWORD      biClrUsed;        DWORD      biClrImportant;} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;我們?cè)诘?10Editor看看(圖如下):

關(guān)于高度為負(fù)的問(wèn)題,在第一節(jié)已經(jīng)說(shuō)明,不知道的同學(xué)請(qǐng)從文章最上面的鏈接進(jìn)入第一節(jié)。在此不再說(shuō)明。

那么問(wèn)題就簡(jiǎn)單了,現(xiàn)在這個(gè)程序的思路就是:

1.用C/C++代碼讀取圖片文件里面的這兩個(gè)結(jié)構(gòu)體。

2.讀取這個(gè)文件到內(nèi)存中。

3.獲取bfOffBIts,再獲取alpha通道(+4)。

4.把數(shù)據(jù)拆分,插入到alpha通道。

5.保存文件。

6.讀取被修改文件的alpha通道,組合成字符串。

理論就是這么簡(jiǎn)單:

下面是程序源碼打包下載地址:

http://download.csdn.net/detail/qq78442761/9747338

下面是程序源碼:

dwBmpSize.h

#pragma  once#include <string>#include <Windows.h>using namespace std;class CBMPHide{public:	CBMPHide();	~CBMPHide();	bool setBmpFileName(char* szFileName);	//設(shè)置Bmp文件名	int getBmpWidth();	//獲取寬度	int getBmpHeight();	//獲取高度	int getBmpBitCount();	//獲取Bit總數(shù)	bool save();	bool hideString2BMP(char* szStr2Hide);	//隱藏String到BMP文件中	void showStringInBmp(char* szBmpFIleName=NULL);	//展示private:	DWORD dwBmpSize;	//圖片文件大小	string sBmpFileName;	LPBYTE pBuf;	//用于存放圖片信息的內(nèi)存	BITMAPFILEHEADER* m_fileHdr;	BITMAPINFOHEADER* m_infoHdr;};dwBmpSIze.cpp

#include "dwBmpSize.h"CBMPHide::CBMPHide(){	sBmpFileName = "";	pBuf = 0;	dwBmpSize = 0;}CBMPHide::~CBMPHide(){}bool CBMPHide::setBmpFileName(char* szFileName){	this->sBmpFileName = szFileName;	if (pBuf)	//如果已經(jīng)生成就釋放掉	{		delete[]pBuf;	}	HANDLE hfile = CreateFileA(szFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);	if (hfile == INVALID_HANDLE_VALUE)	{		return false;	}	//和struct BITMAPFILEHEADER bmfh里面的 bfSize的大小應(yīng)該是一樣的。	dwBmpSize = GetFileSize(hfile, 0);	//獲取文件的大小	pBuf = new byte[dwBmpSize];	DWORD dwRead = 0;	ReadFile(hfile, pBuf, dwBmpSize, &dwRead, 0);	if (dwRead != dwBmpSize)	{		delete[]pBuf;		pBuf = 0;		return false;	}	CloseHandle(hfile);	m_fileHdr = (BITMAPFILEHEADER*)pBuf;	m_infoHdr = (BITMAPINFOHEADER*)(pBuf + sizeof(BITMAPFILEHEADER));	return true;	//成功話就是文件的內(nèi)容讀取到pBuf里面}int CBMPHide::getBmpWidth(){	return m_infoHdr->biWidth;}int CBMPHide::getBmpHeight(){	return m_infoHdr->biHeight;}int CBMPHide::getBmpBitCount(){	return m_infoHdr->biBitCount;}bool CBMPHide::save(){	string sDstFileName = sBmpFileName + ".hide.bmp";	HANDLE hfile = CreateFileA(sDstFileName.c_str(),		GENERIC_READ | GENERIC_WRITE,		FILE_SHARE_READ | FILE_SHARE_WRITE,		NULL,		CREATE_ALWAYS, 0, 0);	if (hfile == INVALID_HANDLE_VALUE)	{		return false;	}	DWORD dwWritten = 0;	WriteFile(hfile, pBuf, dwBmpSize, &dwWritten, 0);	if (dwBmpSize != dwWritten)	{		return false;	}	CloseHandle(hfile);	return true;}//隱藏一個(gè)字符串到圖片中,把字符串拆成字節(jié),寫(xiě)入每個(gè)像素的alpha通道中bool CBMPHide::hideString2BMP(char* szStr2Hide){	LPBYTE pAlpha = pBuf + m_fileHdr->bfOffBits + 3;	//第一個(gè)像素的通道位置	int nHide;	//成功隱藏的字節(jié)數(shù)	//每次循環(huán)寫(xiě)入一個(gè)字節(jié),吸入alpha通道	//(pAlpha - pBuf) < m_fileHdr->bfSize這個(gè)是判斷字符串是太大,圖片不能隱藏	for (nHide = 0; (pAlpha - pBuf) < m_fileHdr->bfSize && szStr2Hide[nHide] != 0; nHide++, pAlpha += 4)	{		*pAlpha = szStr2Hide[nHide];	//寫(xiě)入一個(gè)字節(jié)	}	return true;}void CBMPHide::showStringInBmp(char* szBmpFIleName/*=NULL*/){	string sDstFileName="";	if (szBmpFIleName == 0)	{		sDstFileName = sBmpFileName + ".hide.bmp";	}	else		sDstFileName = szBmpFIleName;	HANDLE hfile = CreateFileA(sDstFileName.c_str(),		GENERIC_READ | GENERIC_WRITE,		FILE_SHARE_READ | FILE_SHARE_WRITE,		NULL,		OPEN_EXISTING, 0, 0);	if (hfile == INVALID_HANDLE_VALUE)	{		return;	}	DWORD dwSize = GetFileSize(hfile, 0);	LPBYTE pBuf1 = new byte[dwSize];	DWORD dwRead = 0;	ReadFile(hfile, pBuf1, dwSize, &dwRead, 0);	CloseHandle(hfile);	//文件內(nèi)容讀取到pBuf1中	BITMAPFILEHEADER *pHdr = (BITMAPFILEHEADER *)pBuf1;	LPBYTE pStr = pBuf1 + pHdr->bfOffBits + 3;	char szTmp[1280];	RtlZeroMemory(szTmp, 1280);	for (int i = 0; i < 1280; i++)	{		if (*pStr == 0 || *pStr == 0xFF)		{			break;		}		szTmp[i] = *pStr;		pStr += 4;	}	printf_s(szTmp);	delete[]pBuf1;}

main.h

#include <stdio.h>#include "dwBmpSize.h"int main(){	CBMPHide hide;	hide.setBmpFileName("test.bmp");	printf_s("test.bmp width:%d,height:%d,bitCount%d/n",		hide.getBmpWidth(),		hide.getBmpHeight(),		hide.getBmpBitCount());	hide.hideString2BMP("Hello Word");	hide.save();	hide.showStringInBmp("test.bmp.hide.bmp");	getchar();	return 0;}程序運(yùn)行結(jié)果如下:

在此不一一舉出。

在這里:可能出現(xiàn)特殊情況,比如寫(xiě)入了0或oxFF(判斷自有數(shù)據(jù)是否結(jié)束標(biāo)志)

在下面一節(jié)中,我們解決這個(gè)問(wèn)題,并且,把一個(gè)不大的txt文本插入到圖片里面去。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 芦溪县| 司法| 江川县| 龙口市| 尚志市| 大悟县| 巴东县| 达日县| 公主岭市| 铜鼓县| 商南县| 交口县| 广昌县| 福鼎市| 阳泉市| 平湖市| 新巴尔虎左旗| 台南市| 焦作市| 凤城市| 广灵县| 巴中市| 乐陵市| 常德市| 启东市| 安新县| 松滋市| 焦作市| 玉林市| 莱州市| 广南县| 观塘区| 县级市| 林州市| 华阴市| 鲁甸县| 洛阳市| 双桥区| 乾安县| 新龙县| 调兵山市|