如何在Swift中将字符串哈希到SHA512?

时间:2015-05-17 05:37:16

标签: swift sha512 cryptoswift

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

4 个答案:

答案 0 :(得分:8)

解决 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: "")
    }

}

答案 1 :(得分:3)

我发现所有的答案都可以,但如果我们应该有一个真正的通用解决方案,我认为我们需要提升一个级别。

CC_LONG只是UInt32,不支持非常大的数据结构。

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

首先我们创建一个基础:

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)
    }
}

为方便起见,我们对Data进行了扩展:

extension Data {
    func sha512() -> Data {
        let s = Sha512()
        s.update(data: self)
        return s.final()
    }
}

最后一个String的扩展程序:

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

此解决方案可用于Sha256,MD5等,以便通过Apple的CommonCrypto获得真正的通用解决方案。

答案 2 :(得分:2)

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("")
}

答案 3 :(得分:2)

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

如果你有一个桥接头文件,你很幸运!只需将其添加到该文件

即可
#import <CommonCrypto/CommonCrypto.h>

There are some articles about different ways to do that.

然后你可以使用这段代码让sha512可用于你选择的任何字符串。

swift 5

extension String {

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