Download
62 lines 1.9 KiBNomsuModified 2019-03-27 raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
#!/usr/bin/env nomsu -V7.0.0
###
    This file defines some actions for hashing files and looking up files by hash.
    
use "filesystem"
use "base64"

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

lua> "local \$use_sha1, \$hashlib = pcall(require, 'openssl.digest')"
test:
    assume (hash "hello world") == (hash "hello world")
    if ((hash "hello world") == (hash "goodbye")):
        fail ("
            Hash collision:
                (hash "hello world") = \(hash "hello world")
                (hash "goodbye") = \(hash "goodbye")
        ")
    
    assume
        (
            hash ("
                This is a really long string meant to stress test the hashing function and
                ensure that it's not overflowing with long inputs.
            ")
        ) != "inf"
    
    if ((hash "\000") == (hash "\000\000\000\000\000")):
        fail "Incorrect hashing of null strings"
    
    if $use_sha1:
        assume ((hash "hello world") == "Kq5sNclPz7QV2+lfQIuc6R7oRu0=")

if $use_sha1:
    external:
        (hash $) means:
            $hash = (=lua "\$hashlib.new('sha1'):final(\$)")
            return (base64 $hash)
..else:
    ### TODO: remove warning?
    say ("
        \027[31;1mWARNING: OpenSSL module not found. Defaulting to a non-cryptographically secure \
        ..hash function.\027[0m
    ")
    
    external:
        (hash $) means:
            $bytes = ($, bytes)
            $hash = ($bytes.1 << 7)
            for $i in (2 to #$bytes):
                $hash = ((1000003 * $hash) ~ $bytes.$i)
            $hash = ($hash ~ #$bytes)
            return "\$hash"

external:
    (file with hash $hash) means:
        for $filename in (files for "."):
            $contents = (read file $filename)
            $file_hash = (hash $contents)
            if ($file_hash == $hash):
                return $filename
    
    (hash of file $filename) parses as (hash (read file $filename))