首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WinApi压缩,python3解压缩

WinApi压缩,python3解压缩
EN

Stack Overflow用户
提问于 2020-05-07 19:56:08
回答 1查看 651关注 0票数 1

我有一个小型客户端应用程序,可以在windows机器上运行。它是用C/C++编写的(更多用C语言编写)。我希望保持较小的规模,因此我不希望使用外部库,而在客户端坚持使用WinAPI。

另一方面,我有一个后端服务器,它是用python3实现的。在这里,我很高兴使用任何现有的库。现在,我想增加压缩层,以提高传输速度。我遇到的问题是,WinAPI似乎只提供:

代码语言:javascript
复制
// source: https://learn.microsoft.com/en-us/windows/win32/cmpapi/using-the-compression-api
XPRESS
XPRESS with Huffman encoding 
MSZIP  
LZMS

这似乎是一个独特的Microsoft压缩算法实现,我找不到一种方法来解压缩python3服务器端的数据。

我遗漏了什么吗?我想听听一些解决办法:)

提前感谢

更新

我决定按照注释中的建议使用zlib https://zlib.net/。提示使用ctype的答案也非常有趣,但毫无疑问,我的后端正在UNIX系统上运行。

当我再次编译客户端部分时--多线程CRT (而不是DLL) --我遇到了一些问题,因为zlib是重新链接到Muli线程的DLL上的。如果有人提出过这样的问题,我在这里找到了一个非常简单的解决方案:https://yongweiwu.wordpress.com/2017/10/02/a-journey-of-purely-static-linking/,我将在这里复制粘贴它:

代码语言:javascript
复制
zlib
This part requires a small change to the build script (for version 1.2.11).
I need to open win32\Makefile.msc and change all occurrences of ‘-MD’ to ‘-MT’. 
Then these commands will work:

nmake -f win32\Makefile.msc zlib.lib
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-08 05:07:58

我找到了这个Python脚本,并对其进行了反向工程,以生产处理WinAPI压缩/解压缩的快速库。基本上,您可以使用ctypes并从Python调用WinAPI。请记住,我还没有对此进行过广泛的测试,但是它应该给您一个很好的起点:)

编辑:根据请求,我已经包含了compressdecompress函数的实现,以防链接中断。

代码语言:javascript
复制
def compress(UncompressedBuffer, UncompressedBufferSize, Format, Engine):
    CompressedBuffer = (ctypes.c_ubyte * UncompressedBufferSize)()
    CompressionFormatAndEngine = ctypes.c_uint16(Format.value | Engine.value)

    CompressBufferWorkSpaceSize = ctypes.c_uint32()
    CompressFragmentWorkSpaceSize = ctypes.c_uint32()
    WorkSpace = (CompressFragmentWorkSpaceSize.value * ctypes.c_ubyte)()
    FinalCompressedSize = ctypes.c_uint32()

    WinDLLCall(RtlGetCompressionWorkSpaceSize,
               CompressionFormatAndEngine,
               ctypes.byref(CompressBufferWorkSpaceSize),
               ctypes.byref(CompressFragmentWorkSpaceSize))

    WinDLLCall(RtlCompressBuffer,
              CompressionFormatAndEngine,
              ctypes.byref(UncompressedBuffer),
              ctypes.c_uint32(UncompressedBufferSize),
              ctypes.byref(CompressedBuffer),
              ctypes.c_uint32(UncompressedBufferSize),
              UncompressedChunkSize,
              ctypes.byref(FinalCompressedSize),
              ctypes.byref(WorkSpace))

    return CompressedBuffer, FinalCompressedSize

def decompress(CompressedBuffer, CompressedBufferSize, UncompressedBufferSize, Format):
    UncompressedBuffer = (ctypes.c_ubyte * UncompressedBufferSize)()
    FinalUncompressedSize = ctypes.c_uint32()

    WinDLLCall(RtlDecompressBuffer,
               Format,
               ctypes.byref(UncompressedBuffer),
               ctypes.c_uint32(UncompressedBufferSize),
               ctypes.byref(CompressedBuffer),
               ctypes.c_uint32(CompressedBufferSize),
               ctypes.byref(FinalUncompressedSize))

    return UncompressedBuffer, FinalUncompressedSize

加载WinAPI函数的代码如下:

代码语言:javascript
复制
import ctypes

RtlDecompressBuffer = ctypes.windll.ntdll.RtlDecompressBuffer
RtlCompressBuffer = ctypes.windll.ntdll.RtlCompressBuffer
RtlGetCompressionWorkSpaceSize = ctypes.windll.ntdll.RtlGetCompressionWorkSpaceSize

下面是一些其他有用的资源,如果您最后修改了这些资源的话:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61666617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档