gpt4 book ai didi

ios - 快速读取任意数量位的方法

转载 作者:搜寻专家 更新时间:2023-10-31 08:04:53 24 4
gpt4 key购买 nike

我正在尝试快速地进行一些二进制文件解析,虽然我的工作正常,但我遇到的情况是我有可变字段。

我的所有解析都在默认情况下工作

我抓

1-bit field
1-bit field
1-bit field
11-bits field
1-bit field
(optional) 4-bit field
(optional) 4-bit field
1-bit field
2-bit field
(optional) 4-bit field
5-bit field
6-bit field
(optional) 6-bit field
(optional) 24-bit field
(junk data - up until byte buffer 0 - 7 bits as needed)

大部分数据只使用一组特定的可选值,所以我已经开始编写类来处理这些数据。我的一般方法是创建一个指针结构,然后从中构造一个字节数组:

let rawData: NSMutableData = NSMutableData(data: input_nsdata)
var ptr: UnsafeMutablePointer<UInt8> = UnsafeMutablePointer<UInt8(rawData.mutableBytes)
bytes = UnsafeMutableBufferPointer<UInt8>(start: ptr, count: rawData.length - offset)

所以我最终使用了一个 [UInt8] 数组,我可以用类似于以下的方式进行解析:

let b1 = (bytes[3] & 0x01) << 5
let b2 = (bytes[4] & 0xF8) >> 3
return Int(b1 | b2)

所以我遇到麻烦的地方是可选字段,因为我的数据并不具体位于字节边界上,一切都变得复杂起来。在理想的世界中,我可能只是直接使用指针并根据需要按字节推进它,但是,我不知道将指针推进 3 位 - 这让我想到了我的问题

处理我的情况的最佳方法是什么?

我想到的一个想法是提出反射(reflect)可选字段的各种结构,但我不确定如何快速创建位对齐的打包结构。

我最好的方法是什么?需要说明的是 - 初始 1 位 字段确定设置了哪些可选字段。

最佳答案

如果字段不在字节边界上,那么你必须保持跟踪当前字节和字节内的当前位位置。

这是一个允许读取任意数字的可能解决方案数据数组中的位并进行所有簿记。唯一的限制是 nextBits() 的结果必须适合 UInt(32 位或 64 位,具体取决于平台)。

struct BitReader {

private let data : [UInt8]
private var byteOffset : Int
private var bitOffset : Int

init(data : [UInt8]) {
self.data = data
self.byteOffset = 0
self.bitOffset = 0
}

func remainingBits() -> Int {
return 8 * (data.count - byteOffset) - bitOffset
}

mutating func nextBits(numBits : Int) -> UInt {
precondition(numBits <= remainingBits(), "attempt to read more bits than available")

var bits = numBits // remaining bits to read
var result : UInt = 0 // result accumulator

// Read remaining bits from current byte:
if bitOffset > 0 {
if bitOffset + bits < 8 {
result = (UInt(data[byteOffset]) & UInt(0xFF >> bitOffset)) >> UInt(8 - bitOffset - bits)
bitOffset += bits
return result
} else {
result = UInt(data[byteOffset]) & UInt(0xFF >> bitOffset)
bits = bits - (8 - bitOffset)
bitOffset = 0
byteOffset = byteOffset + 1
}
}

// Read entire bytes:
while bits >= 8 {
result = (result << UInt(8)) + UInt(data[byteOffset])
byteOffset = byteOffset + 1
bits = bits - 8
}

// Read remaining bits:
if bits > 0 {
result = (result << UInt(bits)) + (UInt(data[byteOffset]) >> UInt(8 - bits))
bitOffset = bits
}

return result
}
}

示例用法:

let data : [UInt8] = ... your data ...
var bitReader = BitReader(data: data)

let b1 = bitReader.nextBits(1)
let b2 = bitReader.nextBits(1)
let b3 = bitReader.nextBits(1)
let b4 = bitReader.nextBits(11)
let b5 = bitReader.nextBits(1)
if b1 > 0 {
let b6 = bitReader.nextBits(4)
let b7 = bitReader.nextBits(4)
}
// ... and so on ...

还有另一种可能的实现方式,比较简单也许更有效。它将字节收集到 UInt 中,并且然后一步提取结果。这里的限制是 numBits + 7 必须小于或等于到 UInt 中的位数(32 或 64)。 (当然 UInt可以替换为 UInt64 以使其独立于平台。)

struct BitReader {
private let data : [UInt8]
private var byteOffset = 0
private var currentValue : UInt = 0 // Bits which still have to be consumed
private var currentBits = 0 // Number of valid bits in `currentValue`

init(data : [UInt8]) {
self.data = data
}

func remainingBits() -> Int {
return 8 * (data.count - byteOffset) + currentBits
}

mutating func nextBits(numBits : Int) -> UInt {
precondition(numBits <= remainingBits(), "attempt to read more bits than available")

// Collect bytes until we have enough bits:
while currentBits < numBits {
currentValue = (currentValue << 8) + UInt(data[byteOffset])
currentBits = currentBits + 8
byteOffset = byteOffset + 1
}

// Extract result:
let remaining = currentBits - numBits
let result = currentValue >> UInt(remaining)

// Update remaining bits:
currentValue = currentValue & UInt(1 << remaining - 1)
currentBits = remaining
return result
}

}

关于ios - 快速读取任意数量位的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35513734/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com