如何将数字转换为字节数组(按位端顺序)
How to convert a number to a bytearray in bit endian order
我正在尝试使用zlib API解压缩在VB6中创建的一些数据。
我已经阅读了qUncompress函数:http://doc.trolltech.com/4.4/qbytearray.html#qUncompress
我已经通过readRawBytes将QDataStream中的数据读取为一个字符数组,然后我将其转换为QByteArray进行解压缩。我有压缩的长度和预期的解压缩长度,但我没有得到从qUncompress返回的任何内容。
然而,我需要以big-endian格式预先准备预期的解压缩长度。有人做过这件事并有一个例子吗?
我在时代中没有使用过VB6,所以我希望这是大致正确的。我认为vb6将()用于数组索引。如果我做错了什么,请告诉我。
查看qUncompress文档,您应该将数据放在QByteArray中,从字节5开始(在本例中,我假设您将数组索引基数设置为1)。
假设数组名为qArr,预期的未压缩大小为size。在"big-endian"表示中,第一个字节位于第一个地址。
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)
这有道理吗?
如果您需要little-endian,您可以颠倒索引的顺序(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 的Byte字段
诀窍是使用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
看起来您想要一个C代码块来解压缩一些zlib压缩数据。在这种情况下,您是否可以实际使用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生成的数据,并在调用qUncompression之前在C++中预先设置长度。
Mike G发布了一个VB解决方案。如果你想在C++中完成,那么你有两个选择,要么在QByteArray的开头添加长度,要么直接调用zlib的uncompress。在这两种情况下,qCompress和qUncompress的Qt源代码(corelib/tools/qbyterarray.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,因为您的数据没有预先准备好长度。
感谢您的帮助,非常有用。
我得到了可以使用的代码:
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);
- 按顺序声明的字符数组重叠
- C++ 替换字节数组中项的顺序
- 按字母顺序打印存储在字符数组中的信息
- 按字母顺序对结构内数组变量中的名称进行排序
- 从数组中删除非唯一值、保持顺序和不使用向量的最佳方法?
- C++按字母顺序排列的字符串数组
- 未按顺序出现在数组中的小写字母
- 如何在 c++ 中按字母顺序排列数组中的字符串?
- 如何在c++中更改数组的顺序
- 如何更改数组中2个对象的顺序
- 在 C++98/03 中以相反的顺序将 C 数组附加到向量,而无需 for 循环
- 如何检查 2 个 c++ 数组在 O(1) 或 O(log n) 时间复杂度中是否相同(所有元素都相同,顺序很重要)?
- 是否有任何内置函数可以检查给定的两个数字在给定整数数组中的顺序是否相同?
- C++ MDC final-在字符类型的数组结构中按字母顺序对记录中的名称进行排序
- 如何在 C++ 中将从文本文件中读取的元素推送和弹出到数组中,并按 Revserse 顺序输出堆栈?
- 查找数组的第一个和最后一个索引,其中 from 和 to 元素的顺序总和最大
- 按字母顺序排序字符数组,然后按长度排序
- 按顺序遍历 AVL 树,将值保存在数组中
- 如何加快非顺序数组填充
- 在几个顺序数组元素中输入相同的值