7

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

4

5 回答 5

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

}
于 2017-03-03T12:37:31.330 回答
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 一起获得良好的真正通用解决方案。

于 2017-06-30T22:00:16.770 回答
2

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

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

#import <CommonCrypto/CommonCrypto.h>

有一些关于不同方法的文章。

然后,您可以使用这段代码让 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: "")
    }
}
于 2017-03-08T12:51:45.473 回答
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("")
}
于 2016-05-18T13:41:23.663 回答
0

斯威夫特 5

对于字符串,此方法对我有用

func SHA512(string: String) -> String {
    let length = Int(CC_SHA512_DIGEST_LENGTH)
    let messageData = string.data(using:.utf8)!
    var digestData = Data(count: length)
    
    _ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
        messageData.withUnsafeBytes { messageBytes -> UInt8 in
            if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
                let messageLength = CC_LONG(messageData.count)
                CC_SHA512(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
            }
            return 0
        }
    }
    return digestData.map { String(format: "%02hhx", $0) }.joined()
}

如果您只需要数据删除 .map { String(format: "%02hhx", $0):

func SHA512(string: String) -> Data {
    let length = Int(CC_SHA512_DIGEST_LENGTH)
    let messageData = string.data(using:.utf8)!
    var digestData = Data(count: length)

    _ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
        messageData.withUnsafeBytes { messageBytes -> UInt8 in
            if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
                let messageLength = CC_LONG(messageData.count)
                CC_SHA512(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
            }
            return 0
        }
    }
    return digestData
}
于 2022-02-04T18:16:55.243 回答