aboutsummaryrefslogtreecommitdiff
path: root/lib/file_hash.nom
blob: 6fdb2f418b9b351197b52211ef9cc6b897d021b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/env nomsu -V4.8.8.6
#
    This file defines some actions for hashing files and looking up files by hash.

use "lib/os.nom"
use "lib/base64.nom"

lua> "local \%use_sha1, \%hashlib = pcall(require, 'openssl.digest')"

test:
    assume (hash "hello world") == (hash "hello world")
    assume ((hash "hello world") != (hash "goodbye")) or barf "\
        ..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"
    
    assume ((hash "\000") != (hash "\000\000\000\000\000")) or barf "\
        ..Incorrect hashing of null strings"
    if %use_sha1:
        assume ((hash "hello world") == "Kq5sNclPz7QV2+lfQIuc6R7oRu0=")
if %use_sha1:
    action [hash %]:
        %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"
    action [hash %]:
        %bytes = (%::bytes)
        %hash = (%bytes.1 << 7)
        for %i in 2 to (size of %bytes):
            %hash = ((1000003 * %hash) ~ %bytes.%i)
        %hash = (%hash ~ (size of %bytes))
        return "\%hash"

action [file with hash %hash]:
    for file %filename in ".":
        %contents = (read file %filename)
        %file_hash = (hash %contents)
        if (%file_hash == %hash): return %filename

parse [hash of file %filename] as (hash (read file %filename))