btv.hash
btv.hash.file(path, algo)
btv.hash.file(path[, algo]) -> promise of the file’s lowercase-hex digest. The
streaming member of the btv.hash.* family (the in-memory string hashers and the
incremental btv.hash.new live in hash.lua): hashing a file is I/O, so it routes
through the fs machinery rather than reading the file into Lua first. The server
streams the file in fixed 64 KiB chunks and folds each into the hasher, so a 300 MB
file costs 64 KiB of memory — not 300 MB, as btv.hash.sha256(btv.await(btv.fs.read(path)))
would. On a remote/browser build the hashing runs entirely on the daemon; only the
short digest crosses the wire, never the file’s bytes. algo is one of "sha1" /
"sha256" / "sha512" / "md5" (default "sha256"); an unknown algorithm rejects (EINVAL).
Defined in fs.lua.
btv.hash.sha1(data)
btv.hash.sha1(data) -> the SHA-1 digest of data, a 40-character lowercase-hex
string. data is hashed as raw bytes (binary-safe). Good for content addressing
and cache keys; NOT collision-resistant, so never rely on it for security.
Defined in hash.lua.
btv.hash.sha256(data)
btv.hash.sha256(data) -> the SHA-256 digest of data, a 64-character lowercase-hex
string. data is hashed as raw bytes (binary-safe). The usual default for a
checksum or content hash.
Defined in hash.lua.
btv.hash.sha512(data)
btv.hash.sha512(data) -> the SHA-512 digest of data, a 128-character lowercase-hex
string. data is hashed as raw bytes (binary-safe).
Defined in hash.lua.
btv.hash.md5(data)
btv.hash.md5(data) -> the MD5 digest of data, a 32-character lowercase-hex string.
data is hashed as raw bytes (binary-safe). For checksums and cache keys only —
MD5 is cryptographically broken; never use it for security.
Defined in hash.lua.
btv.hash.new(algo)
btv.hash.new(algo) -> an incremental hasher for data that arrives in pieces — a
subprocess’s stdout, a download — so you can hash a stream as it flows without ever
holding it all in memory. algo is one of "sha1" / "sha256" / "sha512" / "md5"; an
unknown name errors here, at construction. The returned object has two methods:
h:update(chunk) -- fold more raw bytes in; call as many times as you like
h:hexdigest() -- lowercase-hex digest of everything fed so far. NON-consuming:
you may read an intermediate digest and keep updating after.
Drive it from a stream with btv.await_each — feed each chunk in as it arrives:
btv.async(function()
local h = btv.hash.new("sha256")
for batch in btv.await_each(btv.run_stream({ cmd = "curl", args = { "-s", url } })) do
for _, line in ipairs(batch) do h:update(line) end
end
print(h:hexdigest())
end)()
Note btv.run_stream is line-oriented (newlines are stripped from each batch). For a
byte-exact digest of arbitrary binary output, feed the raw chunks from
btv.process.open’s on_stdout instead. To digest a file on disk, prefer btv.hash.file,
which streams the file server-side and never sends its bytes to Lua.
Defined in hash.lua.