Skip to content

CrazyFanFan/FileHash

Repository files navigation

FileHash

A Swift library to calculate file hashes.

Installation (Swift Package Manager)

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")
]

Usage

Single File (Sync)

import FileHash

let path = "/path/to/file"

let md5 = FileHasher.md5(ofFileAtPath: path)
let sha1 = FileHasher.sha1(ofFileAtPath: path)
let sha256 = FileHasher.hash(.sha256, ofFileAtPath: path)

All APIs accept String?. Passing nil returns nil.

Chunk Size Tuning

Hashing reads file content in chunks. You can change the chunk size per call:

let md5 = FileHasher.md5(ofFileAtPath: path, chunkSize: .kb(256))
let sha512 = FileHasher.sha512(ofFileAtPath: path, chunkSize: .mb(1))

The chunk size is clamped into a safe range:

  • ChunkSize.minChunkSize (.kb(1))
  • ChunkSize.maxChunkSize (.mb(1))

Single File (Async)

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 {
  let md5 = await FileHasher.md5(ofFileAtPath: path, chunkSize: .kb(64))
  let sha256 = await FileHasher.hash(.sha256, ofFileAtPath: path, chunkSize: .kb(64))
  _ = (md5, sha256)
}

Batch Hashing

Hash multiple file paths while keeping the same ordering as input:

let paths: [String?] = ["/a.txt", "/b.txt", nil]

let md5s = FileHasher.hash(.md5, ofFileAtPaths: paths, chunkSize: .kb(64))
let pairs = 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 {
  let results = await FileHasher.hash(.md5, ofFileAtPaths: paths, chunkSize: .kb(64), maxConcurrentTasks: 4)
  _ = results
}

Streaming Results (AsyncStream)

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 {
  for await item in FileHasher.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.

Migration Notes

If you used the old Hasher name, it is now deprecated and renamed to FileHasher.

@available(*, deprecated, renamed: "FileHasher")
public typealias Hasher = FileHasher
    let path = "file_path_string"
    let md5 = FileHasher.md5(ofFileAtPath: path)
    let sha1 = FileHasher.hash(.sha1, ofFileAtPath: path)

About

A swift libray to calculate file hash.

Resources

License

Stars

Watchers

Forks

Packages

No packages published