简体   繁体   English

如何在 Swift 中将 Int 转换为 4 字节的字节数组?

[英]How to convert Int to byte array of 4 bytes in Swift?

I'm using Swift and trying to convert an Int (for example: -1333) to a byte array of 4 bytes.我正在使用 Swift 并尝试将 Int(例如:-1333)转换为 4 字节的字节数组。 I was able to convert an Int to an array of 8 bytes (-1333 becomes [255, 255, 255, 255, 255, 255, 250, 203]), but I need it to be 4 bytes.我能够将 Int 转换为 8 个字节的数组(-1333 变为 [255, 255, 255, 255, 255, 255, 250, 203]),但我需要它是 4 个字节。 I know that there are ways to do this in other languages like Java, but is there a way for Swift?我知道有其他语言可以做到这一点,比如 Java,但是 Swift 有办法吗? Here's my code: (I used THIS answer)这是我的代码:(我使用了这个答案)

func createByteArray(originalValue: Int)->[UInt8]{
        var result:[UInt8]=Array()

            var _number:Int = originalValue

            let mask_8Bit=0xFF

            var c=0
            var size: Int = MemoryLayout.size(ofValue: originalValue)
            for i in (0..<size).reversed(){
                //at: 0 -> insert at the beginning of the array
                result.insert(UInt8( _number&mask_8Bit),at:0)
                _number >>= 8 //shift 8 times from left to right
            }

        return result
    }

In Java an integer is always 32-bit, but in Swift it can be 32-bit or 64-bit, depending on the platform.在 Java 中,整数总是 32 位,但在 Swift 中,它可以是 32 位或 64 位,具体取决于平台。 Your code creates a byte array with the same size as that of the Int type, on a 64-bit platform that are 8 bytes.您的代码在 8 个字节的 64 位平台上创建一个与Int类型大小相同的字节数组。

If you want to restrict the conversion to 32-bit integers then use Int32 instead of Int , the result will then be an array of 4 bytes, independent of the platform.如果要将转换限制为 32 位整数,则使用Int32而不是Int ,结果将是 4 个字节的数组,与平台无关。

An alternative conversion method is另一种转换方法是

let value: Int32 = -1333
let array = withUnsafeBytes(of: value.bigEndian, Array.init)
print(array) // [255, 255, 250, 203]

Or as a generic function for integer type of all sizes:或者作为所有大小的整数类型的通用函数:

func byteArray<T>(from value: T) -> [UInt8] where T: FixedWidthInteger {
    withUnsafeBytes(of: value.bigEndian, Array.init)
}

Example:例子:

print(byteArray(from: -1333))        // [255, 255, 255, 255, 255, 255, 250, 203]
print(byteArray(from: Int32(-1333))) // [255, 255, 250, 203]
print(byteArray(from: Int16(-1333))) // [250, 203]

However, not like Java using big endian, iOS platform uses 'little endian' instead.但是,不像 Java 使用大端,iOS 平台使用“小端”代替。 So if it would be所以如果是

let value: Int32 = -1333
let array2 = withUnsafeBytes(of: value.littleEndian, Array.init)// [203, 250, 255, 255]

You can verify it by wrapping the value into data with below extension and check the bytes您可以通过将值包装到具有以下扩展名的数据中来验证它并检查字节

extension FixedWidthInteger {
    var data: Data {
        let data = withUnsafeBytes(of: self) { Data($0) }
        return data
    }
}
value.data

Just a reminder for those iOS developers who are digging into memory layout.只是提醒那些正在研究 memory 布局的 iOS 开发人员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM