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