diff --git a/docs/content/templates/functions.md b/docs/content/templates/functions.md index 979e603f9..e36e814d3 100644 --- a/docs/content/templates/functions.md +++ b/docs/content/templates/functions.md @@ -595,6 +595,33 @@ CJK-like languages. ``` +### md5 + +`md5` hashes the given input and returns its MD5 checksum. + +```html +{{ md5 "Hello world, gophers!" }} + +``` + +This can be useful if you want to use Gravatar for generating a unique avatar: + +```html + +``` + + +### sha1 + +`sha1` hashes the given input and returns its SHA1 checksum. + +```html +{{ sha1 "Hello world, gophers!" }} + +``` + + + ## URLs ### absURL, relURL diff --git a/tpl/template_funcs.go b/tpl/template_funcs.go index d42d9e5e4..1cbc7d32b 100644 --- a/tpl/template_funcs.go +++ b/tpl/template_funcs.go @@ -15,7 +15,10 @@ package tpl import ( "bytes" + _md5 "crypto/md5" + _sha1 "crypto/sha1" "encoding/base64" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -1501,6 +1504,28 @@ func singularize(in interface{}) (string, error) { return inflect.Singularize(word), nil } +// md5 hashes the given input and returns its MD5 checksum +func md5(in interface{}) (string, error) { + conv, err := cast.ToStringE(in) + if err != nil { + return "", err + } + + hash := _md5.Sum([]byte(conv)) + return hex.EncodeToString(hash[:]), nil +} + +// sha1 hashes the given input and returns its SHA1 checksum +func sha1(in interface{}) (string, error) { + conv, err := cast.ToStringE(in) + if err != nil { + return "", err + } + + hash := _sha1.Sum([]byte(conv)) + return hex.EncodeToString(hash[:]), nil +} + func init() { funcMap = template.FuncMap{ "absURL": func(a string) template.HTML { return template.HTML(helpers.AbsURL(a)) }, @@ -1538,6 +1563,7 @@ func init() { "lower": func(a string) string { return strings.ToLower(a) }, "lt": lt, "markdownify": markdownify, + "md5": md5, "mod": mod, "modBool": modBool, "mul": func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '*') }, @@ -1556,6 +1582,7 @@ func init() { "sanitizeURL": helpers.SanitizeURL, "sanitizeurl": helpers.SanitizeURL, "seq": helpers.Seq, + "sha1": sha1, "shuffle": shuffle, "singularize": singularize, "slice": slice, diff --git a/tpl/template_funcs_test.go b/tpl/template_funcs_test.go index 02d31fe94..878b31d20 100644 --- a/tpl/template_funcs_test.go +++ b/tpl/template_funcs_test.go @@ -99,6 +99,8 @@ seq: {{ seq 3 }} sort: {{ slice "B" "C" "A" | sort }} delimit: {{ delimit (slice "A" "B" "C") ", " " and " }} jsonify: {{ (slice "A" "B" "C") | jsonify }} +md5: {{ md5 "Hello world, gophers!" }} +sha1: {{ sha1 "Hello world, gophers!" }} ` expected := `chomp:

Blockhead

dateFormat: Wednesday, Jan 21, 2015 @@ -134,6 +136,8 @@ seq: [1 2 3] sort: [A B C] delimit: A, B and C jsonify: ["A","B","C"] +md5: b3029f756f98f79e7f1b7f1d1f0dd53b +sha1: c8b5b0e33d408246e30f53e32b8f7627a7a649d4 ` var b bytes.Buffer @@ -155,7 +159,7 @@ jsonify: ["A","B","C"] err = templ.Execute(&b, &data) if err != nil { - t.Fatal("Gott error on execute", err) + t.Fatal("Got error on execute", err) } if b.String() != expected { @@ -2056,3 +2060,51 @@ func TestBase64Encode(t *testing.T) { t.Error("Expected error from base64Encode") } } + +func TestMD5(t *testing.T) { + for i, this := range []struct { + input string + expectedHash string + }{ + {"Hello world, gophers!", "b3029f756f98f79e7f1b7f1d1f0dd53b"}, + {"Lorem ipsum dolor", "06ce65ac476fc656bea3fca5d02cfd81"}, + } { + result, err := md5(this.input) + if err != nil { + t.Errorf("md5 returned error: %s", err) + } + + if result != this.expectedHash { + t.Errorf("[%d] md5: expected '%s', got '%s'", i, this.expectedHash, result) + } + + _, err = md5(t) + if err == nil { + t.Error("Expected error from md5") + } + } +} + +func TestSHA1(t *testing.T) { + for i, this := range []struct { + input string + expectedHash string + }{ + {"Hello world, gophers!", "c8b5b0e33d408246e30f53e32b8f7627a7a649d4"}, + {"Lorem ipsum dolor", "45f75b844be4d17b3394c6701768daf39419c99b"}, + } { + result, err := sha1(this.input) + if err != nil { + t.Errorf("sha1 returned error: %s", err) + } + + if result != this.expectedHash { + t.Errorf("[%d] sha1: expected '%s', got '%s'", i, this.expectedHash, result) + } + + _, err = sha1(t) + if err == nil { + t.Error("Expected error from sha1") + } + } +}