如何将Objective-C的bytes属性转换为Swift?附异或函数移植示例
Objective-C 异或数据函数转 Swift 实现方案
原 Objective-C 函数
这个函数的作用是接收两个 NSData 对象,根据指定的结果长度,循环对两个数据的字节进行异或操作(超出自身长度时循环取字节),最终返回异或后的 NSData:
- (NSData *)xorData1:(NSData *)data1 data2:(NSData *)data2 resultLength:(NSInteger)length { const char *data1Bytes = [data1 bytes]; const char *data2Bytes = [data2 bytes]; NSMutableData *xorData = [[NSMutableData alloc] init]; for (int i = 0; i < length; i++) { const char xorByte = data1Bytes[i % data1.length] ^ data2Bytes[i % data2.length]; [xorData appendBytes:&xorByte length:1]; } return xorData; }
你的 Swift 代码存在的问题
你写的 Swift 版本有几个需要修正的点:
- 无需引入
CommonCrypto,原函数不依赖该库 - 硬编码结果长度为
kCCKeySizeAES128,丢失了原函数的灵活性 - 直接通过下标访问
Data字节的方式错误,Swift 的Data需要通过安全的字节缓冲区访问 - 可以用 Swift 原生的
Data替代NSMutableData,更符合 Swift 编码习惯
正确的 Swift 实现
基础实现(与原 OC 逻辑完全对齐)
func xor(data1: Data, data2: Data, resultLength: Int) -> Data { // 安全获取数据字节指针,并校验数据有效性 guard let data1Bytes = data1.withUnsafeBytes({ $0.bindMemory(to: UInt8.self).baseAddress }), let data2Bytes = data2.withUnsafeBytes({ $0.bindMemory(to: UInt8.self).baseAddress }), data1.count > 0, data2.count > 0 else { return Data() } var result = Data(capacity: resultLength) for i in 0..<resultLength { let byte1 = data1Bytes[i % data1.count] let byte2 = data2Bytes[i % data2.count] result.append(byte1 ^ byte2) } return result }
简洁版(利用 Swift 序列特性)
如果想要更简洁的写法,可以用 Swift 的序列生成循环索引,代码更紧凑但逻辑一致:
func xor(data1: Data, data2: Data, resultLength: Int) -> Data { guard data1.count > 0, data2.count > 0 else { return Data() } // 生成循环索引序列 let cycle1 = sequence(first: 0) { ($0 + 1) % data1.count } let cycle2 = sequence(first: 0) { ($0 + 1) % data2.count } // 映射生成异或后的字节数组,再转为 Data return Data(zip(zip(cycle1, cycle2), 0..<resultLength).map { data1[$0.0.0] ^ data2[$0.0.1] }) }
内容的提问来源于stack exchange,提问作者kunass2
相关产品推荐
相关产品推荐

