diff --git a/README.md b/README.md index 1e766fd..b2954c9 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,16 @@ $ echo '{{ file "hello" }}' | korvike Hello World ``` +- `{{ hash }}` + Hash string with given algorithm (supported algorithms: md5, sha1, sha256, sha512) + ```console + $ echo '{{ hash "sha256" "this is a test" }}' | korvike + 2e99758548972a8e8822ad47fa1017ff72f06f3ff6a016851f45c398732bc50c + ``` - `{{ markdown }}` Format the source using a markdown parser ```console - $ echo '{{ markdown "# headline" | korvike }}' + $ echo '{{ markdown "# headline" }}' | korvike

headline

``` - `{{ now }}` diff --git a/functions/func_hash.go b/functions/func_hash.go new file mode 100644 index 0000000..3f93333 --- /dev/null +++ b/functions/func_hash.go @@ -0,0 +1,40 @@ +package functions + +import ( + "crypto/md5" + "crypto/sha1" + "crypto/sha256" + "crypto/sha512" + "errors" + "fmt" + "hash" +) + +func init() { + registerFunction("hash", func(name string, v ...string) (string, error) { + if len(v) < 1 { + return "", errors.New("no string to hash") + } + + var hash hash.Hash + switch name { + case "md5": + hash = md5.New() + case "sha1": + hash = sha1.New() + case "sha256": + hash = sha256.New() + case "sha512": + hash = sha512.New() + + default: + return "", fmt.Errorf("hash algo %q not supported", name) + } + + if _, err := hash.Write([]byte(v[0])); err != nil { + return "", fmt.Errorf("writing to hash: %w", err) + } + + return fmt.Sprintf("%x", hash.Sum(nil)), nil + }) +} diff --git a/functions/func_test.go b/functions/func_test.go index fa722a0..ff8f1d0 100644 --- a/functions/func_test.go +++ b/functions/func_test.go @@ -73,6 +73,20 @@ func Test_file(t *testing.T) { } } +func Test_hash(t *testing.T) { + input := "I'm a string to hash" + for algo, exp := range map[string]string{ + "md5": "d5adddaa0fd9f924b85e7874dc85f814", + "sha1": "bd41599338445f401b8d3751fbe718e8a0b52004", + "sha256": "ba32f090baf28862816a10da05509b31393704184ae49c68f9eb2933afa9e4d1", + "sha512": "3288edcff4f28526fe8ecfb6d5182f2a446ab0572550c9591d1f5cacd377397af25c0274c9c2428c35422d215ccdc304d0353c093c76e750f9d7c4d54e64eed8", + } { + if res := renderHelper(fmt.Sprintf("{{ hash %q %q }}", algo, input), nil); res != exp { + t.Errorf("Hash algo %q yield unexpected result: exp=%q res=%q", algo, exp, res) + } + } +} + func Test_now(t *testing.T) { if _, err := time.Parse(time.RFC3339Nano, renderHelper(fmt.Sprintf("{{now %q}}", time.RFC3339Nano), nil)); err != nil { t.Errorf("[now] did not produce expected time format")