这是我用md5的swift 3.0的代码,但是UnsafePointer
有3个地方的错误,我该如何解决?
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
}
答案 0 :(得分:0)
将整数变量的(little-endian)值复制到
一个字节数组,你可以使用UnsafeMutableRawBufferPointer
方法
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
}
总而言之,你的方法就变成了
$query = $this->createQuery();
$query->statement('
SELECT *
FROM tx_myext_domain_model_item
WHERE uid NOT IN(
SELECT foreign_uid FROM tx_myext_item_object_mm
)
');
$query->execute();