Ios 在Swift中使用SecRandomCopyBytes

Ios 在Swift中使用SecRandomCopyBytes,ios,swift,swift3,swift5,Ios,Swift,Swift3,Swift5,我想在Swift 3.0中使用SecRandomCopyBytes生成随机字节。下面是我在Swift 2.2中是如何做到这一点的 private static func generateRandomBytes() -> String? { let data = NSMutableData(length: Int(32)) let result = SecRandomCopyBytes(kSecRandomDefault, 32, UnsafeMutablePointer&

我想在Swift 3.0中使用
SecRandomCopyBytes
生成随机字节。下面是我在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
    }
}
有人知道如何解决这个问题吗


谢谢

你很接近,但是
返回
在关闭返回中 从闭包,而不是从外部功能。 因此,在中只应调用
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
    }
}
Swift 5更新:

func generateRandomBytes() -> String? {

    var keyData = Data(count: 32)
    let result = keyData.withUnsafeMutableBytes {
        SecRandomCopyBytes(kSecRandomDefault, 32, $0.baseAddress!)
    }
    if result == errSecSuccess {
        return keyData.base64EncodedString()
    } else {
        print("Problem generating random bytes")
        return nil
    }
}

您很接近,但是
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
    }
}
Swift 5更新:

func generateRandomBytes() -> String? {

    var keyData = Data(count: 32)
    let result = keyData.withUnsafeMutableBytes {
        SecRandomCopyBytes(kSecRandomDefault, 32, $0.baseAddress!)
    }
    if result == errSecSuccess {
        return keyData.base64EncodedString()
    } else {
        print("Problem generating random bytes")
        return nil
    }
}
据了解,它与此类似:

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
        }
    }
}
据了解,它与此类似:

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
        }
    }
}
这是使用Swift 5实现功能的最简单和“最快捷”的方法:

func generateRandomBytes() -> String? {
    var bytes = [UInt8](repeating: 0, count: 32)
    let result = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)

    guard result == errSecSuccess else {
        print("Problem generating random bytes")
        return nil
    }

    return Data(bytes).base64EncodedString()
}
通常,当函数的控制流取决于表达式的成功或失败或非零值的存在时,最好在Swift中使用保护语句,而不是if/else语句。

这是使用Swift 5实现函数的最简单和“最快速”的方法:

func generateRandomBytes() -> String? {
    var bytes = [UInt8](repeating: 0, count: 32)
    let result = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)

    guard result == errSecSuccess else {
        print("Problem generating random bytes")
        return nil
    }

    return Data(bytes).base64EncodedString()
}

通常,在Swift中,当函数的控制流取决于表达式的成功或失败或非零值的存在时,最好使用guard语句,而不是if/else语句。

@CodeOverRide:感谢您解决了“重叠访问”问题。我简化了一点,没有必要复制数据。在闭包中不使用
keyData.count
就足够了。是的,刚刚发现这是不需要的。这在Swift 5中不再有效,因为现在
withunsafemtablebytes
公开了
unsafemtablerawbufferpointer
而不是
unsafemtablepointer
@MartinR,我们是否可以使用
SecRandomCopyBytes
,在
arc4random_uniform()
这样的范围内生成一个随机数?@AnkitJayaswal:不是现成的,但实现起来并不太困难(与中类似)。但请注意,从Swift 4.2开始,Swift标准库提供了一个随机数生成器,根据提供的随机数生成器是加密安全的。@CodeOverRide:感谢您解决了“重叠访问”问题。我简化了一点,没有必要复制数据。在闭包中不使用
keyData.count
就足够了。是的,刚刚发现这是不需要的。这在Swift 5中不再有效,因为现在
withunsafemtablebytes
公开了
unsafemtablerawbufferpointer
而不是
unsafemtablepointer
@MartinR,我们是否可以使用
SecRandomCopyBytes
,在
arc4random_uniform()
这样的范围内生成一个随机数?@AnkitJayaswal:不是现成的,但实现起来并不太困难(与中类似)。但请注意,从Swift 4.2开始,Swift标准库提供了一个随机数生成器,根据,该生成器是加密安全的。