在Swift中直接将UTF-8字符编码的UInt 32字节转换为UInt 32

wtzytmuj  于 4个月前  发布在  Swift
关注(0)|答案(2)|浏览(63)

下面是字节数组

let byteArray: [UInt8] = [53, 51, 57, 52] //5394

字符串
这是4个字节的UInt 32值编码为UTF-8字符。我可以通过使用字符串字面量获得UInt 32值

let byteArray: [UInt8] = [53, 51, 57, 52]
let string = String(bytes: byteArray, encoding: .utf8)!
print("\(string)")
let intValue = UInt32(string)!


我经常在我的程序中使用大数据集进行这种转换。所以,我不想做这种转换和隐式地展开可选项,我想知道有没有办法直接使用UTF-8字符初始化UInt 32?谢谢!

i86rm4rw

i86rm4rw1#

实际上,如果你的字节表示一个数字的UTF-8表示,但你不能100%确定这是真的,那么做你所做的并安全地展开是处理格式错误的数字的最简单方法。
但是,如果你知道你总是有一个由四个ASCII数字组成的数组,你可以直接进行转换。只要它是以10为基数,你可以简单地通过从ASCII中减去48来获得每个数字,48是0的ASCII表示。

var result: UInt32 = 0

for ascii in byteArray
{
    result = result * 10 + UInt32(ascii) - 48
}
print(result) // 5394

字符串
如果输入不是你所期望的,上面的代码中有几个陷阱。如果数组超过9位,当result溢出时代码会崩溃。如果数组包含ASCII数字以外的字节,你会得到一个无意义的结果。

siotufzp

siotufzp2#

Jeremy的回答是一个好的开始,但我对盲目解析未经验证的输入并在输入格式不正确时崩溃的代码持怀疑态度。
从Jeremy的答案开始,我会创建一个抛出函数:

enum ConverionError: Error {
    case wrongLength(byteArray: [UInt8], length: Int)
    case invalidChar(byteArray: [UInt8], index: Int)
}

func byteArrayToInt(_ byteArray: [UInt8]) throws -> UInt32 {
    var result: UInt32 = 0

    guard byteArray.count == 4 else { throw ConverionError.wrongLength(byteArray: byteArray, length:byteArray.count) }
    for (index, ascii) in byteArray.enumerated()
    {
        guard ascii >= 48 && ascii <= 57 else { throw ConverionError.invalidChar(byteArray: byteArray, index: index) }
        result = result * 10 + UInt32(ascii) - 48
    }
    return result
}

字符串
使用该函数的演示代码:

do {
    let byteArrays: [[UInt8]] = [
        [49, 48, 48, 48],
        [49, 50, 51, 52],
        [49, 48, 48, 48, 48],
        [49, 48, 48, 48, 32],
    ]
    for aByteArray in byteArrays {
        let value = try byteArrayToInt(aByteArray)
        print("Byte array \(aByteArray) = \(value)")

    }
} catch {
    switch error as! ConverionError {
    case .wrongLength(let byteArray, let length):
        print("ByteArray \(byteArray) wrong length. Should be 4 chars. Found \(length) chars instead")
    case .invalidChar(let byteArray, let index):
        print("ByteArray \(byteArray) contains invalid char at index \(index)")
    }
    print("Error converting ")
}


该测试代码的输出如下所示:
字节数组[49,48,48,48] = 1000
字节数组[49,50,51,52] = 1234
ByteArray [49,48,48,48,48]长度错误。应该是4个字符。找到的是5个字符
的事务日志已满

相关问题