Генерация случайных байтов в Swift 3.0
Я хочу, чтобы генерировать случайные байты, используя SecRandomCopyBytes
в Swift 3.0. Вот как я это сделал в Swift 2.2
private static func generateRandomBytes() -> String? {
let data = NSMutableData(length: Int(32))
let result = SecRandomCopyBytes(kSecRandomDefault, 32, UnsafeMutablePointer<UInt8>(data!.mutableBytes))
if result == errSecSuccess {
return data!.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
} else {
print("Problem generating random bytes")
return nil
}
}
в Swift 3 я попытался сделать это так, поскольку я знаю, что концепция unsafemutablebytes теперь другая, но это не позволяет мне вернуться. Если я прокомментирую возвращаемую часть, она все еще говорит Generic Parameter ResultType could not be inferred
fileprivate static func generateRandomBytes() -> String? {
var keyData = Data(count: 32)
_ = keyData.withUnsafeMutableBytes {mutableBytes in
let result = SecRandomCopyBytes(kSecRandomDefault, keyData.count, mutableBytes)
if result == errSecSuccess {
return keyData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
} else {
print("Problem generating random bytes")
return nil
}
}
return nil
}
кто-нибудь знает как это исправить?
спасибо
2 ответов
Вы были близки, но return
внутри закрытия возвращается
от закрытия, не от внешней функции.
Поэтому только SecRandomCopyBytes()
должен быть объявлен в
закрытие, и результат передается обратно.
func generateRandomBytes() -> String? {
var keyData = Data(count: 32)
let result = keyData.withUnsafeMutableBytes {
(mutableBytes: UnsafeMutablePointer<UInt8>) -> Int32 in
SecRandomCopyBytes(kSecRandomDefault, 32, mutableBytes)
}
if result == errSecSuccess {
return keyData.base64EncodedString()
} else {
print("Problem generating random bytes")
return nil
}
}
для "закрытия с одним выражением" тип закрытия может выводиться автоматически, так что это может быть сокращено до
func generateRandomBytes() -> String? {
var keyData = Data(count: 32)
let result = keyData.withUnsafeMutableBytes {
SecRandomCopyBytes(kSecRandomDefault, 32, )
}
if result == errSecSuccess {
return keyData.base64EncodedString()
} else {
print("Problem generating random bytes")
return nil
}
}
по данным Документация Apple это выглядит примерно так:
public func randomData(ofLength length: Int) throws -> Data {
var bytes = [UInt8](repeating: 0, count: length)
let status = SecRandomCopyBytes(kSecRandomDefault, length, &bytes)
if status == errSecSuccess {
return Data(bytes: bytes)
}
// throw an error
}
или в качестве дополнительного инициализатора:
public extension Data {
public init(randomOfLength length: Int) throws {
var bytes = [UInt8](repeating: 0, count: length)
let status = SecRandomCopyBytes(kSecRandomDefault, length, &bytes)
if status == errSecSuccess {
self.init(bytes: bytes)
} else {
// throw an error
}
}
}