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

问题描述 投票:7回答:4

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

swift sha512 cryptoswift
4个回答
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: "")
    }

}

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
投票

斯威夫特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: "")
}

斯威夫特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("")
}

2
投票

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

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

#import <CommonCrypto/CommonCrypto.h>

There are some articles about different ways to do that.

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

迅速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: "")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.