最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++使用API實現(xiàn)數(shù)據(jù)的壓縮與解壓縮

 更新時間:2023年11月22日 16:30:02   作者:微軟技術分享  
在Windows編程中,經(jīng)常會遇到需要對數(shù)據(jù)進行壓縮和解壓縮的情況,本文將深入探討使用Windows API進行數(shù)據(jù)壓縮與解壓縮的過程,感興趣的小伙伴可以了解下

在Windows編程中,經(jīng)常會遇到需要對數(shù)據(jù)進行壓縮和解壓縮的情況,數(shù)據(jù)壓縮是一種常見的優(yōu)化手段,能夠減小數(shù)據(jù)的存儲空間并提高傳輸效率。Windows提供了這些API函數(shù),本文將深入探討使用Windows API進行數(shù)據(jù)壓縮與解壓縮的過程,主要使用ntdll.dll庫中的相關函數(shù)。

RtlGetCompressionWorkSpaceSize

RtlGetCompressionWorkSpaceSize 函數(shù),位于ntdll.dll庫中。該函數(shù)用于獲取數(shù)據(jù)壓縮所需的工作空間大小。CompressionFormatAndEngine參數(shù)指定壓縮格式和引擎,CompressBufferWorkSpaceSizeCompressFragmentWorkSpaceSize分別用于輸出緩沖區(qū)和片段的工作空間大小。

以下是該函數(shù)的聲明:

typedef NTSTATUS(WINAPI *typedef_RtlGetCompressionWorkSpaceSize)(
	_In_  USHORT CompressionFormatAndEngine,
	_Out_ PULONG CompressBufferWorkSpaceSize,
	_Out_ PULONG CompressFragmentWorkSpaceSize
);

該函數(shù)有以下參數(shù):

  • CompressionFormatAndEngine:指定壓縮格式和引擎的參數(shù)。
  • CompressBufferWorkSpaceSize:用于輸出壓縮緩沖區(qū)工作空間大小的指針。
  • CompressFragmentWorkSpaceSize:用于輸出壓縮片段工作空間大小的指針。

函數(shù)返回NTSTATUS類型的狀態(tài)碼,其中STATUS_SUCCESS表示成功執(zhí)行。

在使用這個函數(shù)時,你需要提供足夠大的緩沖區(qū)來存儲工作空間大小。可以按照以下步驟使用該函數(shù):

  • 加載 ntdll.dll 庫。
  • 獲取 RtlGetCompressionWorkSpaceSize 函數(shù)地址。
  • 定義變量用于存儲工作空間大小。
  • 調(diào)用 RtlGetCompressionWorkSpaceSize 函數(shù),獲取工作空間大小。

RtlCompressBuffer

RtlCompressBuffer 同樣位于ntdll.dll庫中。該函數(shù)用于將數(shù)據(jù)進行壓縮。CompressionFormatAndEngine參數(shù)指定壓縮格式和引擎,UncompressedBufferUncompressedBufferSize表示輸入的未壓縮數(shù)據(jù),CompressedBufferCompressedBufferSize表示輸出的壓縮數(shù)據(jù),UncompressedChunkSize表示未壓縮數(shù)據(jù)的塊大小,FinalCompressedSize表示最終壓縮后的大小,WorkSpace表示用于工作的緩沖區(qū)。

以下是該函數(shù)的聲明:

typedef NTSTATUS(WINAPI *typedef_RtlCompressBuffer)(
	_In_  USHORT CompressionFormatAndEngine,
	_In_  PUCHAR UncompressedBuffer,
	_In_  ULONG  UncompressedBufferSize,
	_Out_ PUCHAR CompressedBuffer,
	_In_  ULONG  CompressedBufferSize,
	_In_  ULONG  UncompressedChunkSize,
	_Out_ PULONG FinalCompressedSize,
	_In_  PVOID  WorkSpace
);

該函數(shù)的參數(shù)包括:

  • CompressionFormatAndEngine:指定壓縮格式和引擎的參數(shù)。
  • UncompressedBuffer:指向待壓縮數(shù)據(jù)的指針。
  • UncompressedBufferSize:待壓縮數(shù)據(jù)的大小。
  • CompressedBuffer:指向存儲壓縮數(shù)據(jù)的緩沖區(qū)的指針。
  • CompressedBufferSize:存儲壓縮數(shù)據(jù)的緩沖區(qū)的大小。
  • UncompressedChunkSize:未壓縮的數(shù)據(jù)塊的大小。
  • FinalCompressedSize:用于輸出最終壓縮數(shù)據(jù)的大小的指針。
  • WorkSpace:用于提供工作空間的指針。

函數(shù)返回NTSTATUS類型的狀態(tài)碼,其中STATUS_SUCCESS表示成功執(zhí)行。

在使用這個函數(shù)時,你需要提供足夠大的緩沖區(qū)來存儲壓縮后的數(shù)據(jù)。可以按照以下步驟使用該函數(shù):

  • 加載ntdll.dll庫。
  • 獲取RtlCompressBuffer函數(shù)地址。
  • 定義變量并分配內(nèi)存用于存儲未壓縮的數(shù)據(jù)和壓縮后的數(shù)據(jù)。
  • 定義變量用于存儲工作空間。
  • 調(diào)用RtlCompressBuffer函數(shù),將數(shù)據(jù)進行壓縮。
  • 處理壓縮后的數(shù)據(jù)。

RtlDecompressBuffer

RtlDecompressBuffer 同樣位于ntdll.dll庫中。該函數(shù)用于將壓縮數(shù)據(jù)進行解壓縮。CompressionFormat參數(shù)指定壓縮格式,UncompressedBufferUncompressedBufferSize表示輸出的未壓縮數(shù)據(jù),CompressedBufferCompressedBufferSize表示輸入的壓縮數(shù)據(jù),FinalUncompressedSize表示最終解壓縮后的大小。

以下是該函數(shù)的聲明:

typedef NTSTATUS(WINAPI *typedef_RtlDecompressBuffer)(
	_In_  USHORT CompressionFormat,
	_Out_ PUCHAR UncompressedBuffer,
	_In_  ULONG  UncompressedBufferSize,
	_In_  PUCHAR CompressedBuffer,
	_In_  ULONG  CompressedBufferSize,
	_Out_ PULONG FinalUncompressedSize
);

該函數(shù)的參數(shù)包括:

  • CompressionFormat:指定解壓縮的格式。
  • UncompressedBuffer:指向存儲解壓后數(shù)據(jù)的緩沖區(qū)的指針。
  • UncompressedBufferSize:存儲解壓后數(shù)據(jù)的緩沖區(qū)的大小。
  • CompressedBuffer:指向待解壓數(shù)據(jù)的指針。
  • CompressedBufferSize:待解壓數(shù)據(jù)的大小。
  • FinalUncompressedSize:用于輸出最終解壓后數(shù)據(jù)的大小的指針。

函數(shù)返回NTSTATUS類型的狀態(tài)碼,其中STATUS_SUCCESS表示成功執(zhí)行。

在使用這個函數(shù)時,你需要提供足夠大的緩沖區(qū)來存儲解壓后的數(shù)據(jù)??梢园凑找韵虏襟E使用該函數(shù):

  • 加載ntdll.dll庫。
  • 獲取RtlDecompressBuffer函數(shù)地址。
  • 定義變量并分配內(nèi)存用于存儲待解壓的數(shù)據(jù)和解壓后的數(shù)據(jù)。
  • 調(diào)用RtlDecompressBuffer函數(shù),將數(shù)據(jù)進行解壓。
  • 處理解壓后的數(shù)據(jù)。
// 代碼來源 《WINDOWS黑客編程技術詳解》
// 作者:甘迪文
#include <Windows.h>
#include <iostream>
#include <windef.h>

typedef NTSTATUS(WINAPI *typedef_RtlGetCompressionWorkSpaceSize)(
	_In_  USHORT CompressionFormatAndEngine,
	_Out_ PULONG CompressBufferWorkSpaceSize,
	_Out_ PULONG CompressFragmentWorkSpaceSize
	);

typedef NTSTATUS(WINAPI *typedef_RtlCompressBuffer)(
	_In_  USHORT CompressionFormatAndEngine,
	_In_  PUCHAR UncompressedBuffer,
	_In_  ULONG  UncompressedBufferSize,
	_Out_ PUCHAR CompressedBuffer,
	_In_  ULONG  CompressedBufferSize,
	_In_  ULONG  UncompressedChunkSize,
	_Out_ PULONG FinalCompressedSize,
	_In_  PVOID  WorkSpace
	);

typedef NTSTATUS(WINAPI *typedef_RtlDecompressBuffer)(
	_In_  USHORT CompressionFormat,
	_Out_ PUCHAR UncompressedBuffer,
	_In_  ULONG  UncompressedBufferSize,
	_In_  PUCHAR CompressedBuffer,
	_In_  ULONG  CompressedBufferSize,
	_Out_ PULONG FinalUncompressedSize
	);

// 數(shù)據(jù)壓縮
BOOL CompressData(BYTE *pUncompressData, DWORD dwUncompressDataLength, BYTE **ppCompressData, DWORD *pdwCompressDataLength)
{
	BOOL bRet = FALSE;
	NTSTATUS status = 0;
	HMODULE hModule = NULL;
	typedef_RtlGetCompressionWorkSpaceSize RtlGetCompressionWorkSpaceSize = NULL;
	typedef_RtlCompressBuffer RtlCompressBuffer = NULL;
	DWORD dwWorkSpaceSize = 0, dwFragmentWorkSpaceSize = 0;
	BYTE *pWorkSpace = NULL;
	BYTE *pCompressData = NULL;
	DWORD dwCompressDataLength = 4096;
	DWORD dwFinalCompressSize = 0;
	do
	{
		// 加載 ntdll.dll 
		hModule = ::LoadLibrary("ntdll.dll");
		if (NULL == hModule)
		{
			ShowError("LoadLibrary");
			break;
		}

		// 獲取 RtlGetCompressionWorkSpaceSize 函數(shù)地址
		RtlGetCompressionWorkSpaceSize = (typedef_RtlGetCompressionWorkSpaceSize)::GetProcAddress(hModule, "RtlGetCompressionWorkSpaceSize");
		if (NULL == RtlGetCompressionWorkSpaceSize)
		{
			ShowError("GetProcAddress");
			break;
		}

		// 獲取 RtlCompressBuffer 函數(shù)地址
		RtlCompressBuffer = (typedef_RtlCompressBuffer)::GetProcAddress(hModule, "RtlCompressBuffer");
		if (NULL == RtlCompressBuffer)
		{
			ShowError("GetProcAddress");
			break;
		}

		// 獲取WorkSpqce大小
		status = RtlGetCompressionWorkSpaceSize(COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_STANDARD, &dwWorkSpaceSize, &dwFragmentWorkSpaceSize);
		if (0 != status)
		{
			break;
		}

		// 申請動態(tài)內(nèi)存
		pWorkSpace = new BYTE[dwWorkSpaceSize];
		if (NULL == pWorkSpace)
		{
			break;
		}
		::RtlZeroMemory(pWorkSpace, dwWorkSpaceSize);

		while (TRUE)
		{
			// 申請動態(tài)內(nèi)存
			pCompressData = new BYTE[dwCompressDataLength];
			if (NULL == pCompressData)
			{
				break;
			}
			::RtlZeroMemory(pCompressData, dwCompressDataLength);

			// 調(diào)用RtlCompressBuffer壓縮數(shù)據(jù)
			RtlCompressBuffer(COMPRESSION_FORMAT_LZNT1, pUncompressData, dwUncompressDataLength, pCompressData, dwCompressDataLength, 4096, &dwFinalCompressSize, (PVOID)pWorkSpace);
			if (dwCompressDataLength < dwFinalCompressSize)
			{
				// 釋放內(nèi)存
				if (pCompressData)
				{
					delete[]pCompressData;
					pCompressData = NULL;
				}
				dwCompressDataLength = dwFinalCompressSize;
			}
			else
			{
				break;
			}
		}

		// 返回
		*ppCompressData = pCompressData;
		*pdwCompressDataLength = dwFinalCompressSize;
		bRet = TRUE;

	} while (FALSE);

	// 釋放
	if (pWorkSpace)
	{
		delete[]pWorkSpace;
		pWorkSpace = NULL;
	}
	if (hModule)
	{
		::FreeLibrary(hModule);
	}

	return bRet;
}


// 數(shù)據(jù)解壓縮
BOOL UncompressData(BYTE *pCompressData, DWORD dwCompressDataLength, BYTE **ppUncompressData, DWORD *pdwUncompressDataLength)
{
	BOOL bRet = FALSE;
	HMODULE hModule = NULL;
	typedef_RtlDecompressBuffer RtlDecompressBuffer = NULL;
	BYTE *pUncompressData = NULL;
	DWORD dwUncompressDataLength = 4096;
	DWORD dwFinalUncompressSize = 0;
	do
	{
		// 加載 ntdll.dll 
		hModule = ::LoadLibrary("ntdll.dll");
		if (NULL == hModule)
		{
			break;
		}

		// 獲取 RtlDecompressBuffer 函數(shù)地址
		RtlDecompressBuffer = (typedef_RtlDecompressBuffer)::GetProcAddress(hModule, "RtlDecompressBuffer");
		if (NULL == RtlDecompressBuffer)
		{
			break;
		}

		while (TRUE)
		{
			// 申請動態(tài)內(nèi)存
			pUncompressData = new BYTE[dwUncompressDataLength];
			if (NULL == pUncompressData)
			{
				break;
			}
			::RtlZeroMemory(pUncompressData, dwUncompressDataLength);

			// 調(diào)用RtlCompressBuffer壓縮數(shù)據(jù)
			RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, pUncompressData, dwUncompressDataLength, pCompressData, dwCompressDataLength, &dwFinalUncompressSize);
			if (dwUncompressDataLength < dwFinalUncompressSize)
			{
				// 釋放內(nèi)存
				if (pUncompressData)
				{
					delete[]pUncompressData;
					pUncompressData = NULL;
				}
				dwUncompressDataLength = dwFinalUncompressSize;
			}
			else
			{
				break;
			}
		}

		// 返回
		*ppUncompressData = pUncompressData;
		*pdwUncompressDataLength = dwFinalUncompressSize;
		bRet = TRUE;

	} while (FALSE);

	// 釋放
	if (hModule)
	{
		::FreeLibrary(hModule);
	}

	return bRet;
}

int main(int argc, char *argv[])
{
	DWORD i = 0;
	BOOL bRet = FALSE;
	char szBuffer[] = "DDDDDDDDDDGGGGGGGGGGGG";
	DWORD dwBufferLength = ::lstrlen(szBuffer);
	BYTE *pCompressData = NULL;
	DWORD dwCompressDataLength = 0;
	BYTE *pUncompressData = NULL;
	DWORD dwUncompressDataLength = 0;

	// 壓縮數(shù)據(jù)
	CompressData((BYTE *)szBuffer, dwBufferLength, &pCompressData, &dwCompressDataLength);

	// 解壓數(shù)據(jù)
	UncompressData(pCompressData, dwCompressDataLength, &pUncompressData, &dwUncompressDataLength);

	// 顯示
	printf("原數(shù)據(jù)為:\n");
	for (i = 0; i < dwBufferLength; i++)
	{
		printf("%X ", szBuffer[i]);
	}
	printf("\n\n壓縮數(shù)據(jù)為:\n");
	for (i = 0; i < dwCompressDataLength; i++)
	{
		printf("%X ", pCompressData[i]);
	}
	printf("\n\n解壓縮數(shù)據(jù)為:\n");
	for (i = 0; i < dwUncompressDataLength; i++)
	{
		printf("%X ", pUncompressData[i]);
	}
	printf("\n");

	// 釋放
	if (pUncompressData)
	{
		delete[]pUncompressData;
		pUncompressData = NULL;
	}
	if (pCompressData)
	{
		delete[]pCompressData;
		pCompressData = NULL;
	}

	system("pause");
	return 0;
}

到此這篇關于C/C++使用API實現(xiàn)數(shù)據(jù)的壓縮與解壓縮的文章就介紹到這了,更多相關C++數(shù)據(jù)壓縮與解壓縮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++ windows LOG4plus的使用小結(jié)

    C++ windows LOG4plus的使用小結(jié)

    這篇文章主要介紹了C++ windows LOG4plus的使用小結(jié),本文通過圖文示例代碼相結(jié)合給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • C++未定義行為(undefined behavior)

    C++未定義行為(undefined behavior)

    對于未定義行為,C++標準沒有明確規(guī)定編譯器們應該怎么做,那么執(zhí)行的結(jié)果就是不可預料的。下面我們來詳細探討下
    2017-02-02
  • C語言詳細講解二分查找用法

    C語言詳細講解二分查找用法

    二分查找法,又叫做折半查找法,它是一種效率較高的查找方法。但是,折半查找要求線性表必須采用順序存儲結(jié)構,而且表中元素按關鍵字有序排列
    2022-04-04
  • C++返回值是類名和返回值是引用的區(qū)別及說明

    C++返回值是類名和返回值是引用的區(qū)別及說明

    這篇文章主要介紹了C++返回值是類名和返回值是引用的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C語言的動態(tài)內(nèi)存管理你了解嗎

    C語言的動態(tài)內(nèi)存管理你了解嗎

    這篇文章主要為大家詳細介紹了C語言的動態(tài)內(nèi)存管理,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++靜態(tài)成員變量和靜態(tài)成員函數(shù)的使用方法總結(jié)

    C++靜態(tài)成員變量和靜態(tài)成員函數(shù)的使用方法總結(jié)

    下面小編就為大家?guī)硪黄狢++靜態(tài)成員變量和靜態(tài)成員函數(shù)的使用方法總結(jié)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • c++實現(xiàn)二路歸并排序的示例代碼

    c++實現(xiàn)二路歸并排序的示例代碼

    這篇文章主要介紹了c++實現(xiàn)二路歸并排序的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Qt線程QThread開啟和安全退出的實現(xiàn)

    Qt線程QThread開啟和安全退出的實現(xiàn)

    本文主要介紹了Qt線程QThread開啟和安全退出的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • C++實現(xiàn)電子時鐘效果

    C++實現(xiàn)電子時鐘效果

    這篇文章主要為大家詳細介紹了C++實現(xiàn)電子時鐘效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++編輯距離(動態(tài)規(guī)劃)

    C++編輯距離(動態(tài)規(guī)劃)

    這篇文章主要介紹了C++編輯距離(動態(tài)規(guī)劃),編輯距離是指兩個字符串之間,由一個轉(zhuǎn)成另一個所需的最少編輯操作次數(shù),限免詳細內(nèi)容,需要的小伙伴可以參考一下
    2022-01-01

最新評論

思茅市| 碌曲县| 固阳县| 鞍山市| 黑河市| 玉龙| 琼中| 湘乡市| 舒兰市| 年辖:市辖区| 敦煌市| 鄂州市| 启东市| 西畴县| 葫芦岛市| 溆浦县| 贵德县| 陈巴尔虎旗| 林芝县| 肇庆市| 聂拉木县| 南皮县| 永春县| 炎陵县| 元谋县| 大安市| 灵川县| 托里县| 麻栗坡县| 雷山县| 南雄市| 怀化市| 香河县| 张北县| 新丰县| 朝阳县| 江华| 化州市| 乌拉特后旗| 伊金霍洛旗| 沙雅县|