UnsafePointer使用swift 2.0 swift 3.0
问题描述:
这里是我的代码与swift 3.0 md5,但有一个关于UnsafePointer
与3个地方的错误,我该如何解决它?UnsafePointer使用swift 2.0 swift 3.0
let shift : [UInt32] = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21]
let table: [UInt32] = (0 ..< 64).map { UInt32(0x100000000 * abs(sin(Double($0 + 1)))) }
func md5(message: [UInt8]) -> [UInt8] {
var message = message
var messageLenBits = UInt64(message.count) * 8
message.append(0x80)
while message.count % 64 != 56 {
message.append(0)
}
var lengthBytes = [UInt8](repeating: 0, count: 8)
UnsafeMutablePointer<UInt64>(lengthBytes).memory = messageLenBits.littleEndian
message += lengthBytes
var a : UInt32 = 0x67452301
var b : UInt32 = 0xEFCDAB89
var c : UInt32 = 0x98BADCFE
var d : UInt32 = 0x10325476
for chunkOffset in stride(from: 0, to: message.count, by: 64) {
let chunk = UnsafePointer<UInt32>(UnsafePointer<UInt8>(message) + chunkOffset)
let originalA = a
let originalB = b
let originalC = c
let originalD = d
for j in 0 ..< 64 {
var f : UInt32 = 0
var bufferIndex = j
let round = j >> 4
switch round {
case 0:
f = (b & c) | (~b & d)
case 1:
f = (b & d) | (c & ~d)
bufferIndex = (bufferIndex*5 + 1) & 0x0F
case 2:
f = b^c^d
bufferIndex = (bufferIndex*3 + 5) & 0x0F
case 3:
f = c^(b | ~d)
bufferIndex = (bufferIndex * 7) & 0x0F
default:
assert(false)
}
let sa = shift[(round<<2)|(j&3)]
let tmp = a &+ f &+ UInt32(littleEndian: chunk[bufferIndex]) &+ table[j]
a = d
d = c
c = b
b = b &+ (tmp << sa | tmp >> (32-sa))
}
a = a &+ originalA
b = b &+ originalB
c = c &+ originalC
d = d &+ originalD
}
var result = [UInt8](repeating: 0, count: 16)
for (i, n) in [a, b, c, d].enumerated() {
let pointer = UnsafeMutablePointer<UInt32>.allocate(capacity: 1)
result[i] = UInt8(n.littleEndian)
}
return result
}
答
要的整数变量的(小端)值复制到 一个字节数组可以使用的 UnsafeMutableRawBufferPointer
的storeBytes()
方法:
var lengthBytes = [UInt8](repeating: 0, count: 8)
lengthBytes.withUnsafeMutableBytes {
$0.storeBytes(of: messageLenBits.littleEndian, as: UInt64.self)
}
相同的方法工作复制的最终值为a
,b
,c
, d
进入result
阵列。
重读一个UInt8
指针作为UInt32
指针完成 与withMemoryRebound()
:
(UnsafePointer(message) + chunkOffset).withMemoryRebound(to: UInt32.self, capacity: 16) {
chunk in
// ...
let tmp = a &+ f &+ UInt32(littleEndian: chunk[bufferIndex]) &+ table[j]
// ...
}
全部放在一起,你的方法变得
func md5(message: [UInt8]) -> [UInt8] {
var message = message
let messageLenBits = UInt64(message.count) * 8
message.append(0x80)
while message.count % 64 != 56 {
message.append(0)
}
var lengthBytes = [UInt8](repeating: 0, count: 8)
lengthBytes.withUnsafeMutableBytes {
$0.storeBytes(of: messageLenBits.littleEndian, as: UInt64.self)
}
message += lengthBytes
var a : UInt32 = 0x67452301
var b : UInt32 = 0xEFCDAB89
var c : UInt32 = 0x98BADCFE
var d : UInt32 = 0x10325476
for chunkOffset in stride(from: 0, to: message.count, by: 64) {
(UnsafePointer(message) + chunkOffset).withMemoryRebound(to: UInt32.self, capacity: 16) {
chunk in
let originalA = a
let originalB = b
let originalC = c
let originalD = d
for j in 0 ..< 64 {
var f : UInt32 = 0
var bufferIndex = j
let round = j >> 4
switch round {
case 0:
f = (b & c) | (~b & d)
case 1:
f = (b & d) | (c & ~d)
bufferIndex = (bufferIndex*5 + 1) & 0x0F
case 2:
f = b^c^d
bufferIndex = (bufferIndex*3 + 5) & 0x0F
case 3:
f = c^(b | ~d)
bufferIndex = (bufferIndex * 7) & 0x0F
default:
assert(false)
}
let sa = shift[(round<<2)|(j&3)]
let tmp = a &+ f &+ UInt32(littleEndian: chunk[bufferIndex]) &+ table[j]
a = d
d = c
c = b
b = b &+ (tmp << sa | tmp >> (32-sa))
}
a = a &+ originalA
b = b &+ originalB
c = c &+ originalC
d = d &+ originalD
}
}
var result = [UInt8](repeating: 0, count: 16)
result.withUnsafeMutableBytes { ptr in
ptr.storeBytes(of: a.littleEndian, toByteOffset: 0, as: UInt32.self)
ptr.storeBytes(of: b.littleEndian, toByteOffset: 4, as: UInt32.self)
ptr.storeBytes(of: c.littleEndian, toByteOffset: 8, as: UInt32.self)
ptr.storeBytes(of: d.littleEndian, toByteOffset: 12, as: UInt32.self)
}
return result
}
设移:[UInt32的] = [7,12 ,17,22,5,9,14,20,4,11,16,23,6,10,15,21] let table:[UInt32] =(0 .. Martin