Hash files in chunks

This commit is contained in:
Nikolay Edigaryev 2026-08-12 16:47:54 +01:00
parent 53ceac8e22
commit 5993571088
2 changed files with 21 additions and 1 deletions

View File

@ -7,6 +7,8 @@ enum DigestError: Error {
}
class Digest {
static let fileReadChunkSize = 4 * 1024 * 1024
var hash: SHA256 = SHA256()
func update(_ data: Data) {
@ -22,7 +24,16 @@ class Digest {
}
static func hash(_ url: URL) throws -> String {
hash(try Data(contentsOf: url))
let fh = try FileHandle(forReadingFrom: url)
defer { try? fh.close() }
let digest = Digest()
while let data = try fh.read(upToCount: fileReadChunkSize), !data.isEmpty {
digest.update(data)
}
return digest.finalize()
}
static func hash(_ url: URL, offset: UInt64, size: UInt64) throws -> String {

View File

@ -21,4 +21,13 @@ final class DigestTests: XCTestCase {
XCTAssertEqual(Digest.hash(data), "sha256:d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")
}
func testFileHashingReadsMultipleChunks() throws {
let data = Data(repeating: 0xab, count: Digest.fileReadChunkSize + 1)
let url = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString)
try data.write(to: url)
defer { try? FileManager.default.removeItem(at: url) }
XCTAssertEqual(try Digest.hash(url), Digest.hash(data))
}
}