解压VBA流

VBA工程中,VBA代码是以压缩形式存放在复合文档中。

解压缩的代码如下:

Public Function Decompression(arrByte() As Byte) As Byte()
    ‘解压VBA流
    ‘算法说明:https://msdn.microsoft.com/en-us/library/cc313094(v=office.12).aspx
    Dim CompressedContainer() As Byte
    Dim SignatureByte As Byte
    Dim CompressedHeader As Integer
    Dim CompressedChunkSize As Integer
    Dim CompressedChunkSignature As Integer
    Dim CompressedChunkFlag As Integer
    Dim CompressedChunkData() As Byte
    Dim DecompressedChunk() As Byte
    Dim CompressedCurrent As Integer
    Dim DecompressedBuffer() As Byte
    Dim DecompressedStart As Long
    Dim DecompressedChunkSize As Integer

    If LBound(arrByte) <> 0 Then Exit Function

    CompressedContainer = arrByte
    SignatureByte = CompressedContainer(0)
    If SignatureByte <> 1 Then Exit Function
    CompressedCurrent = 1
    DecompressedStart = 0
    Do While CompressedCurrent < UBound(CompressedContainer)
        CopyMemory CompressedHeader, CompressedContainer(CompressedCurrent), 2
        CompressedChunkSize = ExtractCompressedChunkSize(CompressedHeader)
        CompressedChunkSignature = ExtractCompressedChunkSignature(CompressedHeader)
        CompressedChunkFlag = ExtractCompressedChunkFlag(CompressedHeader)
        If CompressedChunkSignature <> 3 Then Exit Function

        If CompressedChunkFlag = 0 Then
            Call DecompressingRawChunk
        Else
            ReDim CompressedChunkData(0 To CompressedChunkSize - 1)
            CopyMemory CompressedChunkData(0), CompressedContainer(CompressedCurrent + 2), CompressedChunkSize
            Call DecompressingTokenSequence(CompressedChunkData, DecompressedChunk)
            CompressedCurrent = CompressedCurrent + 2 + CompressedChunkSize
        End If
        DecompressedChunkSize = UBound(DecompressedChunk) + 1
        ReDim Preserve DecompressedBuffer(0 To DecompressedStart + DecompressedChunkSize - 1)
        CopyMemory DecompressedBuffer(DecompressedStart), DecompressedChunk(0), DecompressedChunkSize
    Loop

    Decompression = DecompressedBuffer
End Function

Private Sub DecompressingTokenSequence(CompressedData() As Byte, DecompressedChunk() As Byte)
    Dim i As Integer
    Dim FlagByte As Byte
    Dim FlagBit As Byte
    Dim Index As Integer
    Dim DecompressedCurrent As Integer
    Dim CompressedCurrent As Integer
    Dim CompressedEnd As Integer
    Dim CopyToken As Long
    Dim Offset As Integer
    Dim Length As Integer

    ReDim DecompressedChunk(0 To 4098)
    CompressedEnd = UBound(CompressedData)
    DecompressedCurrent = 0
    CompressedCurrent = 0
    Index = 0

    Do
        If Index = 0 Then
            FlagByte = CompressedData(CompressedCurrent)
            CompressedCurrent = CompressedCurrent + 1
            If CompressedCurrent > CompressedEnd Then Exit Do
        End If

        FlagBit = ExtractFlagBit(Index, FlagByte)

        If FlagBit = 0 Then
            DecompressedChunk(DecompressedCurrent) = CompressedData(CompressedCurrent)
            DecompressedCurrent = DecompressedCurrent + 1
            CompressedCurrent = CompressedCurrent + 1
        Else
            CopyMemory CopyToken, CompressedData(CompressedCurrent), 2
            Call UnpackCopyToken(CopyToken, DecompressedCurrent, Offset, Length)
            For i = 1 To Length
                DecompressedChunk(DecompressedCurrent) = DecompressedChunk(DecompressedCurrent - Offset)
                DecompressedCurrent = DecompressedCurrent + 1
            Next
            CompressedCurrent = CompressedCurrent + 2
        End If

        Index = Index + 1
        If Index > 7 Then Index = 0
    Loop Until CompressedCurrent > CompressedEnd

    ReDim Preserve DecompressedChunk(0 To DecompressedCurrent - 1)
End Sub

Private Function ExtractFlagBit(Index As Integer, FlagByte As Byte) As Byte
    ExtractFlagBit = (FlagByte And (2 ^ Index)) / 2 ^ Index
End Function

Private Sub DecompressingRawChunk()
    ‘暂未遇到此种情况,有待日后遇到再调试
    Stop
End Sub

Private Function ExtractCompressedChunkSize(Header As Integer) As Integer
    ExtractCompressedChunkSize = (Header And &HFFF) + 1
End Function

Private Function ExtractCompressedChunkSignature(Header As Integer) As Integer
    Dim Temp As Integer
    Temp = Header And &H7000
    ExtractCompressedChunkSignature = Temp / &H1000
End Function

Private Function ExtractCompressedChunkFlag(Header As Integer) As Integer
    Dim Temp As Integer
    Temp = Header And &H8000
    ExtractCompressedChunkFlag = Temp / &H8000
End Function

Private Sub UnpackCopyToken(CopyToken As Long, DecompressedCurrent As Integer, Out_Offset As Integer, Out_Length As Integer)
    Dim bitCount As Integer

    bitCount = -Int(-Log(DecompressedCurrent) / Log(2))
    If bitCount < 4 Then bitCount = 4
    bitCount = 16 - bitCount
    Out_Length = CopyToken And (2 ^ bitCount - 1)
    Out_Offset = (CopyToken - Out_Length) / 2 ^ bitCount
    Out_Length = Out_Length + 3
    Out_Offset = Out_Offset + 1
End Sub
时间: 2024-10-10 21:09:52

解压VBA流的相关文章

高效同步数据的方法及效率测试--边打包边压缩边传输边解压20150105

有些时候在备份或者同步有很多文件的大目录时(比如几个GB或者几十个GB的数据库目录.log目录),直接scp的话花费的时间较长,虽然可以采用先压缩再传输再解压的方法,传输的数据量确实减少了,但压缩和解压也会耗费很多的时间,总体效果也不令人满意,昨天晚上突发奇想,由于之前做过流媒体视频点播的项目的经验,如果能像看高清视频一样只需要下载完视频文件的metadata头就可以实现边下载边播放,即渐进式下载(http://baike.baidu.com/link?url=fTWQYBTqQr1BisysC

支持文件的流式压缩/解压IP*Works! Zip

IP*Works! Zip是为应用程序添加压缩功能的完全可控件组件包.使用简单.速度快并且效率很高,是一个为桌面和网上应用程序添加压缩和解压缩功能的组件套包./n software IP*Works! Zip支持Zip.Tar.Gzip 和 Jar压缩标准,特别的,它支持流式压缩.加密压缩,在压缩包里就可以直接删除文件.我们目前提供完全可控的纯C# .NET组件.纯Java Beans. 产品特征: IP*Works! Zip基于纯C#代码,是完全可控的.NET组件,不依赖于任何外部代码.是完全

zlib流式解压

zlib实现解压的例子官方已经给出 http://www.zlib.net/zlib_how.html 最常见的解压方式就是现成从堆分配出适合大小的内存,直接向这个内存里解压,这样是不错的,一些情况下这样是非常适合的,但是如果文件很大,需要实现一个流式解压的功能,比如文件非常大,需要向文件系统里写文件. 实现的效果如下:     FILE * file = fopen("text.txt","wb+");     InflateStream inflateStrea

C# 文件流压缩解压

/// <summary> /// 文件流压缩解压 /// </summary> public class ZipHelper { public static int BEST_COMPRESSION = 9; public static int BEST_SPEED = 1; public static int DEFAULT_COMPRESSION = -1; public static int NO_COMPRESSION = 0; #region Deflate压缩 #re

android zip4j之--解压zip文件并实时显示解压进度

Zip文件是我们经常用到压缩文件格式,android中在进行网络请求大批量数据时,通常会采用传递zip文件,这样做即可以减少网络流量的消耗,加快请求的响应速度,又可以减少对存储空间的要求,所以当我们将zip文件读取回来的时候,如何解压就是一个要解决的问题,虽然java本身提供了zip相关的API,但不是很强大,所以我们采用apache开源组织的zip4j,通过这个jar包可以十分轻松的解压zip文件. 回到项目中去,项目中有个需求是从服务器请求杂志,请求回来后给读者展示,但是由于公司自己做的电子

python学习笔记-Day7(configparser模块、shutil、压缩与解压模块、subprocess)

configparser模块 # configparser用于处理特定格式的文件,其本质上是利用open来操作文件 # 下边我们就创建这种特定格式配置文件,来操作以下这里模块方法 --------------test.conf---------------- [section1] # configparser 会认定以中括号括住的为一个节点(node) k1 = 111 # 节点下,每一行配置文件为键值对存在(也可以写成 k2:123) k2 = v2 k3 = 123 k4 = True k1

通过javascript在网页端解压zip文件并查看压缩包内容

WEB前端解压ZIP压缩包 web前端解压zip文件有什么用: 只考虑标准浏览器的话, 服务器只要传输压缩包到客户端, 节约了带宽, 而且节约了传输时间, 听起来好像很厉害的说:     如果前端的代码很多, 而且包含大副的图片,那么就可以把js和css和jpg和png等各种数据通过服务端打包成zip传送到浏览器, 浏览器负责解压, css实用动态生成插入到dom中,js也用globalEval直接执行, jpg或者png各种图片文件由blob流转化为image, 直接插入到浏览器中: html

ZIP压缩算法详细分析及解压实例解释

最近自己实现了一个ZIP压缩数据的解压程序,觉得有必要把ZIP压缩格式进行一下详细总结,数据压缩是一门通信原理和计算机科学都会涉及到的学科,在通信原理中,一般称为信源编码,在计算机科学里,一般称为数据压缩,两者本质上没啥区别,在数学家看来,都是映射.一方面在进行通信的时候,有必要将待传输的数据进行压缩,以减少带宽需求:另一方面,计算机存储数据的时候,为了减少磁盘容量需求,也会将文件进行压缩,尽管现在的网络带宽越来越高,压缩已经不像90年代初那个时候那么迫切,但在很多场合下仍然需要,其中一个原因是

Java实现文件压缩与解压[zip格式,gzip格式]

Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例. zip扮演着归档和压缩两个角色:gzip并不将文件归档,仅只是对单个文件进行压缩,所以,在UNIX平台上,命令tar通常用来创建一个档案文件,然后命令gzip来将档案文件压缩. Java I/O类库还收录了一些能读写压缩格式流的类.要想提供压缩功能,只要把它们包在已有的I/O类的外面就行了.这些类不是Reader和Writer,而是Inpu