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") + } + } +}