问题
I am building a social media application and I would like some help encoding a password string to SHA512 in Swift. I found the CryptoSwift library on GitHub but I am having a hard time loading it into my Swift project and linking it to my project files. Does anyone know how to accomplish this relatively easily? Thanks in advance, Kyle
回答1:
Solution for 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: "")
}
}
回答2:
I find all of the answer ok, but if we should have a true universal solution I think we need to step it up a level.
CC_LONG
is just an UInt32
and will not support really large data structures.
This is my solution in Swift 3:
First we create a foundation:
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)
}
}
For convenience we do an extension for Data
:
extension Data {
func sha512() -> Data {
let s = Sha512()
s.update(data: self)
return s.final()
}
}
And last an extension for String
:
extension String {
func sha512() -> Data {
return self.data(using: .utf8)!.sha512()
}
}
This solution can be used for Sha256, MD5 etc. to get a good true universal solutions with Apple's CommonCrypto.
回答3:
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("")
}
回答4:
You need to import C library CommonCrypto. You cannot just import CommonCrypto to your swift file since it's not a standalone module.
If you have a bridging header file, you are lucky! Just add this to that file
#import <CommonCrypto/CommonCrypto.h>
There are some articles about different ways to do that.
Then you can use this piece of code to have sha512 available for any string of your choice.
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: "")
}
}
来源:https://stackoverflow.com/questions/30283731/how-to-hash-a-string-to-sha512-in-swift