首页 > 解决方案 > 快速将 Int 转换为 UInt8 数组

问题描述

我想快速转换 UInt8 列表中的标准整数。

var x:Int = 2019

2019 可以(例如)用十六进制 7E3 编写,所以我想要某种可以转换为 UInt8 列表的函数,如下所示。

var y:[Uint8] = [0x07, 0xE3]

我已经找到了这个:将整数转换为 UInt8 单位的数组,但他/她正在转换数字的 ascii 符号而不是数字本身。所以他的例子 94887253 应该给出一个类似 [0x05, 0xA7, 0xDD, 0x55] 的列表。

在最好的情况下,我正在寻找的函数具有某种用法,因此我还可以选择结果数组的最小长度,例如

foo(42, length:2) -> [0x00, 0x2A]

或者

foo(42, length:4) -> [0x00, 0x00, 0x00, 0x2A]

标签: swiftintuint8array

解决方案


你可以这样做:

let x: Int = 2019
let length: Int = 2 * MemoryLayout<UInt8>.size  //You could specify the desired length

let a = withUnsafeBytes(of: x) { bytes in
    Array(bytes.prefix(length))
}

let result = Array(a.reversed()) //[7, 227]

或者更一般地说,我们可以使用这个片段的修改版本:

func bytes<U: FixedWidthInteger,V: FixedWidthInteger>(
    of value    : U,
    to type     : V.Type,
    droppingZeros: Bool
    ) -> [V]{

    let sizeInput = MemoryLayout<U>.size
    let sizeOutput = MemoryLayout<V>.size

    precondition(sizeInput >= sizeOutput, "The input memory size should be greater than the output memory size")

    var value = value
    let a =  withUnsafePointer(to: &value, {
        $0.withMemoryRebound(
            to: V.self,
            capacity: sizeInput,
            {
                Array(UnsafeBufferPointer(start: $0, count: sizeInput/sizeOutput))
        })
    })

    let lastNonZeroIndex =
        (droppingZeros ? a.lastIndex { $0 != 0 } : a.indices.last) ?? a.startIndex

    return Array(a[...lastNonZeroIndex].reversed())
}

let x: Int = 2019
bytes(of: x, to: UInt8.self, droppingZeros: true)   // [7, 227]
bytes(of: x, to: UInt8.self, droppingZeros: false)  // [0, 0, 0, 0, 0, 0, 7, 227]

推荐阅读