如何以位端顺序将数字转换为bytearray
-
05-07-2019 - |
题
我正在尝试使用zlib API解压缩在VB6中创建的一些数据。
我已经阅读过qUncompress函数可以实现的: http://doc.trolltech.com/4.4/qbytearray.html#qUncompress
我已经通过readRawBytes从QDataStream读取数据到char中 数组,然后我转换为QByteArray进行解压缩。一世 有压缩的长度和预期的解压长度,但没有得到 从qUncompress回来的任何东西。
但是我需要以big endian格式预先设置预期的解压缩长度。有没有人这样做并有一个例子?
解决方案
我没有在年龄中使用VB6,所以我希望这是近似正确的。我认为 vb6 used()用于数组索引。如果我有什么不对的地方,请告诉我。
查看qUncompress文档,您应该将数据放在QByteArray中,从字节5开始(我将假设您将此数组的索引基数设置为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))并保持计算相同。
其他提示
这就是我可以将仲裁数据从一种格式转换为另一种格式的方法。
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
看起来你想要一个解压缩一些zlib压缩数据的C代码。 在这种情况下,您可以实际使用zlib并将zlib数据提供给它。 zlib主页: http://www.zlib.net/ 。
如果我弄错了,您能否具体说明用于解压缩数据的语言是什么?为什么zlib不是一个选择?
//int length;
byte[] bigEndianBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(length))
相反:
//byte[] bigEndianBytes;
int length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(bigEndianBytes))
我不清楚你的问题是否要在VB中加上长度以便它适合qUncompress直接使用,或者你是否想要像现在这样使用VB生成的数据并预先设置长度在调用qUncompress之前用C ++编写。
这就是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,因为您的数据没有前面的长度。
感谢您的帮助,这很有用。
我得到了代码:
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);