欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

在Windows編程中,經(jīng)常會遇到需要對數(shù)據(jù)進(jìn)行壓縮和解壓縮的情況,數(shù)據(jù)壓縮是一種常見的優(yōu)化手段,能夠減小數(shù)據(jù)的存儲空間并提高傳輸效率。Windows提供了這些API函數(shù),本文將深入探討使用Windows API進(jìn)行數(shù)據(jù)壓縮與解壓縮的過程,主要使用ntdll.dll庫中的相關(guān)函數(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ù)進(jìn)行壓縮。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ù)??梢园凑找韵虏襟E使用該函數(shù):

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

RtlDecompressBuffer

RtlDecompressBuffer 同樣位于ntdll.dll庫中。該函數(shù)用于將壓縮數(shù)據(jù)進(jìn)行解壓縮。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ù)進(jìn)行解壓。
  • 處理解壓后的數(shù)據(jù)。
// 代碼來源 《WINDOWS黑客編程技術(shù)詳解》
// 作者:甘迪文
#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;
}

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

相關(guān)文章

  • C語言實現(xiàn)簡單的掃雷功能

    C語言實現(xiàn)簡單的掃雷功能

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)簡單的掃雷功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++中菱形繼承的解釋與處理詳解

    C++中菱形繼承的解釋與處理詳解

    菱形繼承是多重繼承中跑不掉的,Java拿掉了多重繼承,輔之以接口。C++中雖然沒有明確說明接口這種東西,但是只有純虛函數(shù)的類可以看作Java中的接口,下面這篇文章主要給大家介紹了關(guān)于C++中菱形繼承的解釋與處理的相關(guān)資料,需要的朋友可以參考下
    2022-02-02
  • C語言版簡單掃雷游戲

    C語言版簡單掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了C語言版簡單掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++ float、double判斷是否等于0問題

    C++ float、double判斷是否等于0問題

    這篇文章主要介紹了C++ float、double判斷是否等于0問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • C++Primer筆記之順序容器的使用詳解

    C++Primer筆記之順序容器的使用詳解

    本篇文章對C++Primer 順序容器的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • 詳解C++數(shù)組和數(shù)組名問題(指針、解引用)

    詳解C++數(shù)組和數(shù)組名問題(指針、解引用)

    這篇文章主要介紹了詳解C++數(shù)組和數(shù)組名問題(指針、解引用),指針的實質(zhì)就是個變量,它跟普通變量沒有任何本質(zhì)區(qū)別,指針本身是一個對象,同時指針無需在定義的時候賦值,具體內(nèi)容詳情跟隨小編一起看看吧
    2021-09-09
  • 詳解Linux的SOCKET編程

    詳解Linux的SOCKET編程

    這篇文章主要介紹了Linux的SOCKET編程,并且進(jìn)行了實例講解,需要的朋友可以參考下
    2015-08-08
  • C++實現(xiàn)含附件的郵件發(fā)送功能

    C++實現(xiàn)含附件的郵件發(fā)送功能

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)含附件的郵件發(fā)送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • C語言如何實現(xiàn)循環(huán)輸入

    C語言如何實現(xiàn)循環(huán)輸入

    這篇文章主要介紹了C語言如何實現(xiàn)循環(huán)輸入問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C語言修煉之路函數(shù)篇真題訓(xùn)練上

    C語言修煉之路函數(shù)篇真題訓(xùn)練上

    函數(shù)是一組一起執(zhí)行一個任務(wù)的語句。每個?C?程序都至少有一個函數(shù),即主函數(shù)?main()?,所有簡單的程序都可以定義其他額外的函數(shù)
    2022-03-03

最新評論