如何在Swift中将字符串散列到SHA512?

如何在Swift中将字符串散列到SHA512?,swift,sha512,cryptoswift,Swift,Sha512,Cryptoswift,我正在构建一个社交媒体应用程序,我想得到一些帮助,在Swift中将密码字符串编码为SHA512。我在GitHub上找到了CryptoSwift库,但我很难将它加载到我的Swift项目中,并将其链接到我的项目文件。有人知道如何相对容易地实现这一点吗? 提前感谢,, 凯尔斯威夫特3 func sha512() -> String { let data = self.data(using: .utf8)! var digest = [UInt8](repeating: 0, co

我正在构建一个社交媒体应用程序,我想得到一些帮助,在Swift中将密码字符串编码为SHA512。我在GitHub上找到了CryptoSwift库,但我很难将它加载到我的Swift项目中,并将其链接到我的项目文件。有人知道如何相对容易地实现这一点吗? 提前感谢,,
凯尔

斯威夫特3

func sha512() -> String {
    let data = self.data(using: .utf8)!
    var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
    data.withUnsafeBytes({
        _ = CC_SHA512($0, CC_LONG(data.count), &digest)
    })

    return digest.map({ String(format: "%02hhx", $0) }).joined(separator: "")
}
Swift 2.3

func sha512() -> String {
    let data = self.dataUsingEncoding(NSUTF8StringEncoding)!
    var digest = [UInt8](count:Int(CC_SHA512_DIGEST_LENGTH), repeatedValue: 0)
    CC_SHA512(data.bytes, CC_LONG(data.length), &digest)
    let hexBytes = digest.map { String(format: "%02hhx", $0) }

    return hexBytes.joinWithSeparator("")
}

Swift 3的解决方案:

extension String {

    func sha512() -> String {
        let data = self.data(using: .utf8)!
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
        data.withUnsafeBytes({
            _ = CC_SHA512($0, CC_LONG(data.count), &digest)
        })
        return digest.map({ String(format: "%02hhx", $0) }).joined(separator: "")
    }

}

您需要导入C库CommonCrypto。您不能只将CommonCrypto导入swift文件,因为它不是一个独立的模块

如果你有一个桥接头文件,你是幸运的!只需将此添加到该文件中

#import <CommonCrypto/CommonCrypto.h>

我觉得所有的答案都可以,但如果我们应该有一个真正的通用解决方案,我认为我们需要把它提高一个水平

CC_LONG
只是一个
UInt32
,不支持真正的大型数据结构

这是我在Swift 3中的解决方案:

extension String {

    func sha512() -> String {
        let data = self.data(using: .utf8)!
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
        data.withUnsafeBytes({
            _ = CC_SHA512($0, CC_LONG(data.count), &digest)
        })
        return digest.map({ String(format: "%02hhx", $0) }).joined(separator: "")
    }

}
首先,我们创建一个基金会:

struct Sha512 {
    let context = UnsafeMutablePointer<CC_SHA512_CTX>.allocate(capacity:1)

    init() {
        CC_SHA512_Init(context)
    }

    func update(data: Data) {
        data.withUnsafeBytes { (bytes: UnsafePointer<Int8>) -> Void in
            let end = bytes.advanced(by: data.count)
            for f in sequence(first: bytes, next: { $0.advanced(by: Int(CC_LONG.max)) }).prefix(while: { (current) -> Bool in current < end})  {
                _ = CC_SHA512_Update(context, f, CC_LONG(Swift.min(f.distance(to: end), Int(CC_LONG.max))))
            }
        }
    }

    func final() -> Data {
        var digest = [UInt8](repeating: 0, count:Int(CC_SHA512_DIGEST_LENGTH))
        CC_SHA512_Final(&digest, context)

        return Data(bytes: digest)
    }
}
最后是
字符串的扩展名:

extension String {
    func sha512() -> Data {
        return self.data(using: .utf8)!.sha512()
    }
}

此解决方案可用于Sha256、MD5等,以获得苹果CommonCrypto的真正通用解决方案。

I beliebe CryptoSwift是一种简单的方法:)使用CryptoSwift有什么问题?–你不一定需要第三方框架,你也可以使用苹果的CommonCrypto和轻薄的Swift包装。示例:(您自己的问题:),@MartinR谢谢分享!这个答案真的很有帮助!这篇文章回答了我的问题()。我所要做的就是将SHA1改为SH512。请参阅文档部分,最好避免使用CryptoSwift,除此之外,它比基于普通加密的实现慢500到1000倍。苹果公司的通用密码是经过FIPS认证的,因此经过了严格审查,使用CryptoSwift在正确性和安全性上是一次冒险。想知道
self.data(使用:.utf8)
可能会失败,因为
self
必须是有效的
String
。是的,你是对的。Swift字符串始终是unicode字符串,因此
self.data(使用:.utf8)
永远不会失败。我相应地修改了我的答案。在操场上,我必须导入什么才能访问
CC\ucode
funcs?基础是不够的,因为不能添加桥接头,所以不可能在游戏场中直接使用公共密码。但我读到,通过在桥接头中添加一个带有CommonCrypto的框架是可能的:Hello@sundance,谢谢你的回答。我不太明白字符串(格式:)调用中“%02hhx”的含义;我想知道你能否简单地解释一下。另外,为什么需要迭代字节并使用字符串(格式:)将其转换为字符串,而不是仅使用
base64EncodedString()
?提前谢谢
extension String {
    func sha512() -> Data {
        return self.data(using: .utf8)!.sha512()
    }
}