I find the whole answer in order, but if we have to have a true universal solution, I think we need to increase its level.
CC_LONG is just UInt32 and will not support really large data structures.
This is my solution in Swift 3 :
First we create the 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 are doing an extension for Data :
extension Data { func sha512() -> Data { let s = Sha512() s.update(data: self) return s.final() } }
And the last 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 good real universal solutions with Apple CommonCrypto.
source share