lua-hash is a lightweight, native library providing hash algorithms for Lua.
- On Unix-like distributions, it uses the
OpenSSL
library; - On Windows, it uses the WINAPI
bcrypt
library; - On macOS / iOS, it uses the
CommonCrypto
framework.
Note
lua-hash
is implemented in C, and also compiles as C++.
Algorithm | Description |
---|---|
MD5 | An implementation of MD5 hashing with a 128-bit digest |
SHA1 | An implementation of SHA1 hashing with a 160-bit digest |
SHA256 | An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a 256-bit digest |
SHA384 | An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a 384-bit digest |
SHA512 | An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a 512-bit digest |
Warning
According to Apple (see [1] and [2]), MD5 and SHA1 are considered insecure algorithms, but they are provided for backward compatibility with older services that require it. For new services, prefer SHA512.
Important
On Unix-like operating systems (e.g.: Linux, BSD), lua-hash
depends on the OpenSSL
library:
-
On Debian-based (e.g.: Ubuntu) distributions:
sudo apt install -y libssl-dev
-
On RedHat-based (e.g.: Fedora) distributions:
sudo dnf install openssl-devel
-
On BSD-based (e.g.: FreeBSD) distributions:
pkg install openssl-devel
Assuming that LuaRocks is properly installed and configured on your system, execute the following command:
luarocks install lua-hash
This manner is suitable for (small) text that fits well in the memory.
-- load the library
local hash = require("lua-hash")
-- the text to be hashed
local text = "lua-hash is a cool hashing library"
-- hash 'text' by different algorithms
local MD5_hash = hash.oneshot("MD5", text)
local SHA1_hash = hash.oneshot("SHA1", text)
local SHA256_hash = hash.oneshot("SHA256", text)
local SHA384_hash = hash.oneshot("SHA384", text)
local SHA512_hash = hash.oneshot("SHA512", text)
-- print the hash of 'text' computed by different algorithms
print("MD5 hash is", MD5_hash)
print("SHA1 hash is", SHA1_hash)
print("SHA256 hash is", SHA256_hash)
print("SHA384 hash is", SHA384_hash)
print("SHA512 hash is", SHA512_hash)
By the use of the core API, you can compute a hash of a file of any size (even the huge ones).
-- the file path to compute a SHA512 hash
local filepath = "path/to/some/file"
local file = assert(io.open(filepath, "rb"), "provide the file path as a parameter to this script to compute a SHA512 checksum")
-- load the library
local hash = require("lua-hash")
-- cache the classes
local algorithm = hash.algorithm
local context = hash.context
local digest = hash.digest
-- open the SHA512 algorithm
local algo = algorithm.open("SHA512")
-- create a context for the hash operation
local ctx = context.new(algo)
-- create a message digest
local message = digest.new(ctx)
-- define a size in bytes
-- to read a chunk from
-- disk
local kb = 1024
local size = 16 * kb
local valid = true
-- keep reading the file while
-- it is not finished
while (valid) do
local chunk = file:read(size)
if (chunk == nil) then
valid = false
else
-- hash the chunk read from disk
-- into the context
message:update(chunk)
end
end
-- close the file
file:close()
local output = message:finalize()
print(("%s %s"):format(output, filepath))
-- close the context to free resources
--
-- tip: the context is closed
-- automatically at garbage collection
ctx:close()
-- close the algorithm to free resources
--
-- tip: the algorithm is closed
-- automatically at garbage collection
algo:close()
Tip
In the checksums folder, you can find scripts for each available hashing algorithm on this library.
- Description: The oneshot function provides a quick manner to compute the hash of a text held in memory.
- Signature:
oneshot(name, text)
- Parameters:
- name (
string
): the name of the algorithm. See Supported Algorithms for a list containing the possible values for this parameter. - text (
string
): the text to compute a hash.
- name (
- Return (
string
): A hex string containing the hash of the text.
In order to compute the hash of content that is not suitable to hold in memory, we have to use a verbose approach through in-depth methods. Such specialized methods, split into three classes, were mirrored directly from the C API of the underlying libraries:
- algorithm;
- context;
- digest.
Implementation of a hash algorithm provided by the underlying library.
-
Description: Opens the implementation of a given hash algorithm and initializes resources.
-
Signature:
open(name)
-
Parameters:
- name (
string
): the name of the algorithm. See Supported Algorithms for a list of all the possible algorithms.
- name (
-
Return (
userdata
): A handle to the hash algorithm. -
Remark: In case of failure, this function throws an error. It might happen if the underlying library does not support the hash algorithm identified by the
name
parameter.
- Description: Closes the algorithm and free resources.
- Signature:
algorithm:close()
- Return (
void
)
A manager to process a digest associated to a given hash algorithm
- Description: Creates a new context to the provided algorithm, and initializes resources.
- Signature:
new(algorithm)
- Parameters:
- algorithm (
userdata
): an instance to an algorithm previously opened.
- algorithm (
- Return (
userdata
): A handle to the newly created context. - Remark: In case of failure, this function throws an error. It might happen if the provided hashing algorithm is closed.
- Description: Closes the context and free resources.
- Signature:
context:close()
- Return (
void
)
Allows a message, even the long ones, to be streamed in chunks to the underlying algorithm for the hash computation.
- Description: Creates a new digest bound to a context, and initializes resources.
- Signature:
new(ctx)
- Parameters:
- ctx (
userdata
): an instance of acontext
.
- ctx (
- Return (
userdata
): A handle to the newly created digest. - Remark: In case of failure, this function throws an error. It might happen if the provided context, or algorithm bound to the context, was closed.
- Description: Hashes the data into the context.
- Signature:
digest:update(data)
- Parameters:
- data (
string | table
): the data to be hashed into the context. Ifdata
is a string, the only requirement is that it cannot be an empty string. Otherwise, whendata
is a table, it is expected to be an array of bytes, i.e., elements are integers in 0 - 255 range.
- data (
- Return (
void
) - Remark: In case of failure, this function throws an error. It might happen if the provided context, or algorithm bound to the context, was closed.
- Description: Retrieves the digest value from the context.
- Signature:
digest:finalize(options)
- Parameters:
- options (
nil | table
): whenoptions
is nil or not specified at all, a hex string is returned. Otherwise, whenoptions
is a table, it is mandatory to have a fieldtype
describing the desired return type ('string' or 'table'). Moreover, whentype
is equal to'string'
, an optional boolean fieldhex
can be assigned to signal whether the resulting hash should be formatted as hex string or not.- examples:
- output a hex string:
-- output is a hex string local output = digest:finalize()
- output a hex string:
-- output is a hex string local output = digest:finalize(nil)
- (alternative) output a hex string:
-- output is a hex string local output = digest:finalize({ type = 'string', hex = true })
- output a string (not hex-formatted):
-- output is a raw string, -- but not in hex format. -- Usually, this output string -- contains characters that cannot -- be rendered nicely on the screen. local output = digest:finalize({ type = 'string', hex = false })
- output a table of bytes:
-- output is a table (array) such that -- each element falls in the 0 - 255 range local output = digest:finalize({ type = 'table' })
- output a hex string:
- examples:
- options (
- Return (
string | table
): the resulting hash of the whole set of bytes pushed into the context. - Remark:
- After calling this function, no additional usage of both the context and digest can be made, except for closing them and freeing resources.
- In case of failure, this function throws an error. It might happen if the provided context, or algorithm bound to the context, was closed.
v0.0.1: Initial release.
- Add CMake as a build system.