【问题标题】:How to convert a number to a bytearray in bit endian order如何以位字节序将数字转换为字节数组
【发布时间】:2010-09-15 17:09:21
【问题描述】:

我正在尝试使用 zlib API 解压缩在 VB6 中创建的一些数据。

我已经阅读了 qUncompress 函数可以做到这一点: http://doc.trolltech.com/4.4/qbytearray.html#qUncompress

我已通过 readRawBytes 将 QDataStream 中的数据读入一个字符 数组,然后我将其转换为 QByteArray 进行解压缩。一世 具有压缩长度和预期的解压缩长度,但没有得到 从 qUncompress 返回的任何内容。

但是,我需要以大端格式添加预期的解压缩长度。有没有人这样做过并举个例子?

【问题讨论】:

    标签: c++ qt vb6 compression endianness


    【解决方案1】:

    感谢大家的帮助,很有用。

    我得到了代码:

            char slideStr[currentCompressedLen];
            int slideByteRead = in.readRawData(slideStr, currentCompressedLen);
            QByteArray aInCompBytes = QByteArray(slideStr, slideByteRead);
            aInCompBytesPlusLen = aInCompBytes;
            aInCompBytesPlusLen.prepend(QByteArray::number(currentUnCompressedLen));
            aInUnCompBytes.resize(currentUnCompressedLen);
            aInUnCompBytes = qUncompress(aInCompBytesPlusLen);
    

    【讨论】:

      【解决方案2】:

      这就是我可以将任意数据从一种格式转换为另一种格式的方法。

      Private Type LongByte
          H1 As Byte
          H2 As Byte
          L1 As Byte
          L2 As Byte
      End Type
      
      Private Type LongType
          L As Long
      End Type
      
      Function SwapEndian(ByVal LongData as Long) as Long
        Dim TempL As LongType
        Dim TempLB As LongByte
        Dim TempVar As Long
      
        TempL.L = LongData
        LSet TempLB = TempL
      'Swap is a subroutine I wrote to swap two variables
        Swap TempLB.H1, TempLB.L2
        Swap TempLB.H2, TempLB.L1
        LSet TempL = TempLB
        TempVar = TempL.L
      
        SwapEndian = TempVar
      End Function
      

      如果您正在处理 FileIO,那么您可以使用 TempLB 的字节字段

      诀窍是使用 LSET VB6 的一个不起眼的命令

      如果您使用的是 .NET,那么执行此过程要容易得多。这里的技巧是使用 MemoryStream 来检索和设置各个字节。现在你可以计算 int16/int32/int64。但是,如果您正在处理浮点数据,使用 LSET 或 MemoryStream 会更清晰且更易于调试。

      如果您使用的是 Framework 1.1 或更高版本,那么您将拥有使用字节数组的 BitConvertor 类。

      Private Structure Int32Byte
          Public H1 As Byte
          Public H2 As Byte
          Public L1 As Byte
          Public L2 As Byte
          Public Function Convert() As Integer
              Dim M As New MemoryStream()
              Dim bR As IO.BinaryReader
              Dim bW As New IO.BinaryWriter(M)
              Swap(H1, L2)
              Swap(H2, L1)
              bW.Write(H1)
              bW.Write(H2)
              bW.Write(L1)
              bW.Write(L2)
              M.Seek(0, SeekOrigin.Begin)
              bR = New IO.BinaryReader(M)
              Convert = bR.ReadInt32()
          End Function
      End Structure
      

      【讨论】:

        【解决方案3】:

        从您的问题中我不清楚您是否想在 VB 中添加长度以便它适合 qUncompress 直接使用,或者您是否想像现在一样使用 VB 生成的数据并添加长度在调用 qUncompress 之前在 C++ 中。

        Mike G 有posted 一个 VB 解决方案。如果你想用 C++ 来做,那么你有两个选择,要么在 QByteArray 的开头添加长度,要么直接调用 zlib 的 uncompress。在这两种情况下,qCompress 和 qUncompress 的 Qt 源代码(corelib/tools/qbytearray.cpp)都是很好的参考。

        这是 qCompress 如何将长度(nbytes)添加到 bazip,压缩数据:

        bazip[0] = (nbytes & 0xff000000) >> 24;
        bazip[1] = (nbytes & 0x00ff0000) >> 16;
        bazip[2] = (nbytes & 0x0000ff00) >> 8;
        bazip[3] = (nbytes & 0x000000ff);
        

        bazip 是结果 QByteArray

        或者,如果您想直接调用 uncompress,而不是使用 qUncompress 包装器,它使用的调用是

        baunzip.resize(len);
        res = ::uncompress((uchar*)baunzip.data(), &len,
                                (uchar*)data+4, nbytes-4);
        

        其中 baunzip 是一个 QByteArray。在您的情况下,您将删除 +4 和 -4,因为您的数据没有预先设置长度。

        【讨论】:

          【解决方案4】:
          //int length;
          byte[] bigEndianBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(length))
          

          反过来:

          //byte[] bigEndianBytes;
          int length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(bigEndianBytes))
          

          【讨论】:

          • BitConverter 和 IPAddress 在 vb6 中可用吗?
          【解决方案5】:

          看起来您需要一段 C 代码来解压缩一些 zlib 压缩数据。 在这种情况下,您是否可以实际使用 zlib 并将 zlib 数据提供给它。 zlib 主页:http://www.zlib.net/.

          如果我弄错了,您能否具体说明解压缩数据应该使用什么语言以及为什么不能选择 zlib?

          【讨论】:

          • qCompress/qUncompress 只是 zlib 的一个包装器。
          【解决方案6】:

          我没有在年龄中使用过VB6,所以我希望这是大致正确的。我认为 vb6 使用 () 进行数组索引。如果我有任何问题,请告诉我。

          查看 qUncompress 文档,您应该从第 5 个字节开始将数据放入 QByteArray(我将假设您在本示例中将数组索引基数设置为 1)。

          假设数组名为 qArr,预期的未压缩大小为 Size。 在“大端”表示中,第一个字节位于第一个地址。

          qArr(1) = int(Size/(256*256*256))
          qArr(2) = 255 And int(Size/256*256)
          qArr(3) = 255 And int(Size/256)
          qArr(4) = 255 And int(Size)
          

          这有意义吗?

          如果您需要小端序,您可以颠倒索引的顺序 (qArr(4) - qArr(1)) 并保持计算不变。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-09
            • 1970-01-01
            • 2019-12-13
            • 2018-05-06
            • 2011-02-02
            • 1970-01-01
            • 2019-11-24
            • 1970-01-01
            相关资源
            最近更新 更多