You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET与Node.js的Zlib Deflate压缩兼容性问题求助

VB.NET与Node.js Zlib Deflate压缩兼容性问题解决

问题背景

在实现VB.NET客户端与Node.js服务器通信时,遇到Zlib Deflate压缩的兼容性问题:

  • VB.NET的压缩结果开头是原数据长度的4字节自定义前缀,无标准Zlib头和校验尾
  • Node.js的zlib.deflateSync输出开头为[120,156](标准Zlib Deflate头),结尾带4字节可变的ADLER32校验值
  • 两者核心压缩数据一致,但手动修改VB结果(去掉前4字节、添加[120,156])后,Node.js的inflateSync会提示“unexpected end of file”,需解决VB中生成Node.js所需结尾校验字节的问题

原代码对比

VB.NET压缩代码

Shared Function Compression(buffer As Byte()) As Byte()
    Try
        Dim ms As New MemoryStream()
        Using zipStream As New Compression.DeflateStream(ms, IO.Compression.CompressionMode.Compress, True)
            zipStream.Write(buffer, 0, buffer.Length)
        End Using
        ms.Position = 0
        Dim outStream As New MemoryStream()
        Dim compressed As Byte() = New Byte(ms.Length - 1) {}
        ms.Read(compressed, 0, compressed.Length)
        Dim gzBuffer As Byte() = New Byte(compressed.Length + 3) {}
        System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length)
        System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4)
        Return gzBuffer
    Catch
        Return buffer
    End Try
End Function

调用示例:Compression(stringtobyte("testTESTtestTESTtestTESTtestTEST"))
返回字节数组:[32,0,0,0,43,73,45,46,9,113,13,14,41,193,65,3,0]

Node.js压缩代码

zlib.deflateSync(Buffer.from("testTESTtestTESTtestTESTtestTEST"))

返回字节数组:[120, 156,43,73,45,46,9,113,13,14,41,193,65,3,0,201,232,12,1]

解决方案

要让VB.NET生成符合Node.js Zlib标准的压缩数据,需添加标准Zlib头和ADLER32校验尾:

关键说明

  1. Zlib头[120,156]:
    • 120:标识使用Deflate压缩方法,窗口大小为32KB
    • 156:表示默认压缩级别,且未使用预定义字典
  2. ADLER32校验:Node.js结尾的4字节是原数据的ADLER32校验值,需按大端字节序追加到压缩数据后

修改后的VB.NET代码

Imports System.IO
Imports System.IO.Compression

Shared Function CompressToZlibFormat(buffer As Byte()) As Byte()
    Try
        ' 计算原数据的ADLER32校验值
        Dim adler32 As UInt32 = Adler32.Compute(buffer)
        
        ' 执行Deflate压缩(仅核心压缩数据,不含头和尾)
        Using msCompressed As New MemoryStream()
            Using deflateStream As New DeflateStream(msCompressed, CompressionMode.Compress, True)
                deflateStream.Write(buffer, 0, buffer.Length)
            End Using
            
            ' 组装完整Zlib格式数据:头 + 压缩数据 + ADLER32校验
            Dim compressedData As Byte() = msCompressed.ToArray()
            Dim zlibBuffer As Byte() = New Byte(1 + compressedData.Length + 3) {}
            
            ' 添加标准Zlib头
            zlibBuffer(0) = 120
            zlibBuffer(1) = 156
            
            ' 复制核心压缩数据
            Buffer.BlockCopy(compressedData, 0, zlibBuffer, 2, compressedData.Length)
            
            ' 转换ADLER32为大端字节序并追加
            Dim adlerBytes As Byte() = BitConverter.GetBytes(adler32)
            If BitConverter.IsLittleEndian Then
                Array.Reverse(adlerBytes)
            End If
            Buffer.BlockCopy(adlerBytes, 0, zlibBuffer, 2 + compressedData.Length, 4)
            
            Return zlibBuffer
        End Using
    Catch
        Return buffer
    End Try
End Function

' ADLER32校验计算实现
Public Class Adler32
    Private Const Base As UInt32 = 65521
    Public Shared Function Compute(data As Byte()) As UInt32
        Dim a As UInt32 = 1
        Dim b As UInt32 = 0
        For Each bVal As Byte In data
            a = (a + bVal) Mod Base
            b = (b + a) Mod Base
        Next
        Return (b << 16) Or a
    End Function
End Class

代码效果

修改后的代码生成的压缩数据完全兼容Node.js的zlib.inflateSync,无需手动修改字节数组即可直接完成跨平台解压缩。

内容的提问来源于stack exchange,提问作者Lethalic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 11:31:01