Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I hash a file on iOS using swift 3?

I have a number of files that will live on a server. Users have the ability to create these kinds of files (plists) on-device which will then upload to said server (CloudKit). I would like to unique them by content (the uniquing methodology should be resilient to variations in creation date). My understanding is that I should hash these files in order to obtain unique file names for them. My questions are:

  1. Is my understanding correct that what I want is a hash function?
  2. Which function should I use (from CommonCrypto).
  3. What I need is a digest?
  4. How would I go about it in code? (I assume this should be hashed over an NSData instance?). My understanding from googling around is that I need a bridging header include but beyond that the use of CommonCrypto baffles me. If there is a simpler way using first-party APIs (Apple) I am all ears (I want to avoid using third party code as much as possible).

Thanks so much!

like image 418
iOS Gamer Avatar asked Mar 21 '17 17:03

iOS Gamer


1 Answers

An update using Apple's CryptoKit: You could use a FileHandle to read the data in chunks, and pass these into the hasher:

import CryptoKit

func getSHA256(forFile url: URL) throws -> SHA256.Digest {
    let handle = try FileHandle(forReadingFrom: url)
    var hasher = SHA256()
    while autoreleasepool(invoking: {
        let nextChunk = handle.readData(ofLength: SHA256.blockByteCount)
        guard !nextChunk.isEmpty else { return false }
        hasher.update(data: nextChunk)
        return true
    }) { }
    let digest = hasher.finalize()
    return digest

    // Here's how to convert to string form
    //return digest.map { String(format: "%02hhx", $0) }.joined()
}
like image 77
Apptek Studios Avatar answered Sep 24 '22 15:09

Apptek Studios