如何在Swift中以littleEndian方式反转NSData输出?

Mar*_*ida 6 endianness nsdata swift

嘿家伙我从NSData得到这个输出:<00000100 84000c00 071490fe 4dfbd7e9>

那么我怎样才能在Swift中对其进行字节反转并输出:<00000001 0084000c 1407fe90 fb4de9d7>?

Mar*_*n R 10

这应该可以交换数据中的每对相邻字节.我们的想法是将字节解释为UInt16整数数组并使用内置byteSwapped属性.

func swapUInt16Data(data : NSData) -> NSData {

    // Copy data into UInt16 array:
    let count = data.length / sizeof(UInt16)
    var array = [UInt16](count: count, repeatedValue: 0)
    data.getBytes(&array, length: count * sizeof(UInt16))

    // Swap each integer:
    for i in 0 ..< count {
        array[i] = array[i].byteSwapped // *** (see below)
    }

    // Create NSData from array:
    return NSData(bytes: &array, length: count * sizeof(UInt16))
}
Run Code Online (Sandbox Code Playgroud)

如果您的实际意图是将数据从(外部)大端表示转换为主机(本机)字节顺序(在所有当前的iOS和OS X设备上恰好是小端),那么您应该替换***

array[i] = UInt16(bigEndian: array[i])
Run Code Online (Sandbox Code Playgroud)

例:

var bytes : [UInt8] = [1, 2, 3, 4, 5, 6, 7, 8]
let data = NSData(bytes: &bytes, length: bytes.count)
print(data)
// <01020304 05060708>
print(swapUInt16Data(data))
// <02010403 06050807>
Run Code Online (Sandbox Code Playgroud)

Swift 3的更新:泛型withUnsafeMutableBytes() 方法允许获取UnsafeMutablePointer<UInt16>字节并直接修改它们:

func swapUInt16Data(data : Data) -> Data {
    var mdata = data // make a mutable copy
    let count = data.count / MemoryLayout<UInt16>.size
    mdata.withUnsafeMutableBytes { (i16ptr: UnsafeMutablePointer<UInt16>) in
        for i in 0..<count {
            i16ptr[i] =  i16ptr[i].byteSwapped
        }
    }
    return mdata
}
Run Code Online (Sandbox Code Playgroud)

例:

let data = Data(bytes: [1, 2, 3, 4, 5, 6, 7, 8])
print(data as NSData) // <01020304 05060708>

let swapped = swapUInt16Data(data: data)
print(swapped as NSData) // <02010403 06050807>
Run Code Online (Sandbox Code Playgroud)