A Swift library to calculate file hashes.
Add the package in Xcode (File → Add Packages…) or in Package.swift:
dependencies:[.package(url:"https://github.com/CrazyFanFan/FileHash.git", exact:"0.0.1")]import FileHash
letpath="/path/to/file"letmd5=FileHasher.md5(ofFileAtPath: path)letsha1=FileHasher.sha1(ofFileAtPath: path)letsha256=FileHasher.hash(.sha256, ofFileAtPath: path)All APIs accept String?. Passing nil returns nil.
Hashing reads file content in chunks. You can change the chunk size per call:
letmd5=FileHasher.md5(ofFileAtPath: path, chunkSize:.kb(256))letsha512=FileHasher.sha512(ofFileAtPath: path, chunkSize:.mb(1))The chunk size is clamped into a safe range:
ChunkSize.minChunkSize(.kb(1))ChunkSize.maxChunkSize(.mb(1))
Available on iOS 13 / macOS 10.15 / watchOS 6 / tvOS 13 and newer.
@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0,*)func example(path:String)async{letmd5=awaitFileHasher.md5(ofFileAtPath: path, chunkSize:.kb(64))letsha256=awaitFileHasher.hash(.sha256, ofFileAtPath: path, chunkSize:.kb(64))
_ =(md5, sha256)}Hash multiple file paths while keeping the same ordering as input:
letpaths:[String?]=["/a.txt","/b.txt",nil]letmd5s=FileHasher.hash(.md5, ofFileAtPaths: paths, chunkSize:.kb(64))letpairs=FileHasher.hashPairs(.sha256, ofFileAtPaths: paths, chunkSize:.kb(64))Async batch hashing supports limiting concurrency:
@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0,*)func batchExample(paths:[String?])async{letresults=awaitFileHasher.hash(.md5, ofFileAtPaths: paths, chunkSize:.kb(64), maxConcurrentTasks:4)
_ = results
}If you want progress updates (e.g. update UI as each file completes), use the stream API.
The stream yields (index, path, hash); completion order may differ from input order.
@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0,*)func streamExample(paths:[String?])async{forawaititeminFileHasher.hashStream(.md5, ofFileAtPaths: paths, chunkSize:.kb(64), maxConcurrentTasks:4){print(item.index, item.path ??"nil", item.hash ??"nil")}}Stopping iteration cancels the underlying producer task, which helps avoid wasted work.
If you used the old Hasher name, it is now deprecated and renamed to FileHasher.
@available(*, deprecated, renamed:"FileHasher")publictypealiasHasher=FileHasher let path = "file_path_string"
let md5 = FileHasher.md5(ofFileAtPath: path)
let sha1 = FileHasher.hash(.sha1, ofFileAtPath: path)