aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-07-30 14:11:45 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-07-30 14:11:45 -0700
commit2a12310b25f68208ff0101fce5d0137f267c7394 (patch)
tree28a845cc5aaab477e6a6d87539a88162f5685365
parent43e8da178084184db1701b0abb9d615046b4c51d (diff)
Switching hashes to use base64 instead of hex.
-rw-r--r--lib/base64.nom54
-rw-r--r--lib/file_hash.nom34
2 files changed, 70 insertions, 18 deletions
diff --git a/lib/base64.nom b/lib/base64.nom
new file mode 100644
index 0000000..a5bb9bb
--- /dev/null
+++ b/lib/base64.nom
@@ -0,0 +1,54 @@
+#!/usr/bin/env nomsu -V2.5.5.4
+#
+ This file defines actions for encoding/decoding base 64, as specified in:
+ https://tools.ietf.org/html/rfc4648
+
+%b64_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+%reverse_b64 = (%b64_str.%i = (%i - 1) for %i in 1 to (length of %b64_str))
+%reverse_b64."=" = 0
+test:
+ %cases = ["", "Zg==", "Zm8=", "Zm9v", "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy"]
+ for %len = %encoded in %cases:
+ %plain = "foobar".[1, %len - 1]
+ assume ((base64 %plain) == %encoded) or barf ".."
+ \(quote %plain) base64 encoded to \(quote (base64 %plain)) \
+ ..instead of \(quote %encoded)
+ assume ((base64 decode %encoded) == %plain) or barf ".."
+ \(quote %encoded) base64 decoded to \(quote (base64 decode %encoded)) \
+ ..instead of \(quote %plain)
+
+action [base64 %str, base64 encode %str, %str base64]:
+ %chars = []
+ for %i in 1 to (length of %str) via 3:
+ %bytes = [=lua "\%str:byte(\%i, \(%i + 2))"]
+ add %b64_str.(((%bytes.1 & 252) >> 2) + 1) to %chars
+ if (length of %bytes) is:
+ 3:
+ add %b64_str.(((%bytes.1 & 3) << 4) + ((%bytes.2 & 240) >> 4) + 1) to %chars
+ add %b64_str.(((%bytes.2 & 15) << 2) + ((%bytes.3 & 192) >> 6) + 1) to %chars
+ add %b64_str.((%bytes.3 & 63) + 1) to %chars
+
+ 2:
+ add %b64_str.(((%bytes.1 & 3) << 4) + ((%bytes.2 & 240) >> 4) + 1) to %chars
+ add %b64_str.(((%bytes.2 & 15) << 2) + 1) to %chars
+ add "=" to %chars
+
+ 1:
+ add %b64_str.(((%bytes.1 & 3) << 4) + 1) to %chars
+ add "=" to %chars
+ add "=" to %chars
+
+ return (%chars joined)
+
+action [chr %] (=lua "string.char(\%)")
+action [decode base64 %str, %str base64 decoded, base64 decode %str]:
+ %chars = []
+ for %i in 1 to (length of %str) via 4:
+ %indices = (%reverse_b64.(%str.%) for % in %i to (%i + 3))
+ add (chr ((%indices.1 << 2) + ((%indices.2 & 48) >> 4))) to %chars
+ if (%str.(%i+2) == "="): stop
+ add (chr (((%indices.2 & 15) << 4) + ((%indices.3 & 60) >> 2))) to %chars
+ if (%str.(%i+3) == "="): stop
+ add (chr (((%indices.3 & 3) << 6) + %indices.4)) to %chars
+
+ return (%chars joined)
diff --git a/lib/file_hash.nom b/lib/file_hash.nom
index 8bbdd0a..aef1c78 100644
--- a/lib/file_hash.nom
+++ b/lib/file_hash.nom
@@ -2,25 +2,23 @@
#
This file defines some actions for hashing files and looking up files by hash.
-action [file with hash %hash]:
- lua> ".."
- local Hash = require("openssl.digest")
- for filename in io.popen('find -L . -not -path "*/\\\\.*" -type f -name "*.nom"'):lines() do
- local file = io.open(filename)
- local contents = file:read("*a")
- file:close()
- local hash = Hash.new("sha1"):final(contents)
- local hex = hash:gsub('.', function(c) return string.format('%02x', string.byte(c)) end)
- if hex == \%hash then
- return filename
- end
- end
+use "lib/os.nom"
+use "lib/base64.nom"
+
+%hashlib = (=lua "require('openssl.digest')")
+
+test:
+ assume ((hash "hello world") == "Kq5sNclPz7QV2+lfQIuc6R7oRu0=")
action [hash %, sha1 %]:
- %hashlib = (=lua "require('openssl.digest')")
%hash = (=lua "\%hashlib.new('sha1'):final(\%)")
- return (..)
- =lua ".."
- \%hash:gsub('.', function(c) return string.format('%02x', string.byte(c)) end)
+ return (base64 %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 (sha1 (=lua "io.open(\%filename):read('*a')"))
+parse [hash of file %filename] as (sha1 (read file %filename))