From 4d3bbc0c8894fbc1f72cb80292ba4cbb3ccaa399 Mon Sep 17 00:00:00 2001 From: Tai Groot Date: Mon, 21 Mar 2022 22:44:21 -0700 Subject: [PATCH] Adds hash_test code --- README.md | 17 +++++++++++++++++ hash.go | 35 +++++++++++++++++++++++++++++++++++ hash_test.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 README.md create mode 100644 hash.go create mode 100644 hash_test.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..c516fee --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ + + + - Take in arbitrary input and return a deterministic color + - Color chosen can be limited in several ways: + - only visually / noticibly distinct colors to choose from + - Color exclusions + - dynamic color exclusions (optional terminal context) + - colors within different terminal support classes (i.e. term-256) + + - Offer to return Hex codes (6 digits or 3) + - Offer to return ascii escape codes + - If the input is text, offer to wrap the input text and return the output as a string + + +1. take input as bytes +1. md5 hash the input +1. use modulo against the sum to choose the color to return from the subset of colors selected. diff --git a/hash.go b/hash.go new file mode 100644 index 0000000..4976e2d --- /dev/null +++ b/hash.go @@ -0,0 +1,35 @@ +package go_colorhash + +import ( + "crypto/md5" + "encoding/binary" + "io" +) + +const MaxUint = ^uint(0) +const MaxInt = int(MaxUint >> 1) + +func HashString(s string) int { + h := md5.New() + io.WriteString(h, s) + hashb := h.Sum(nil) + hashb = hashb[len(hashb)-8:] + lsb := binary.BigEndian.Uint64(hashb) + sint := int(lsb) + if sint < 0 { + sint = sint + MaxInt + } + return sint +} +func HashBytes(r io.Reader) int { + h := md5.New() + io.Copy(h, r) + hashb := h.Sum(nil) + hashb = hashb[len(hashb)-8:] + lsb := binary.BigEndian.Uint64(hashb) + sint := int(lsb) + if sint < 0 { + sint = sint + MaxInt + } + return sint +} diff --git a/hash_test.go b/hash_test.go new file mode 100644 index 0000000..a454227 --- /dev/null +++ b/hash_test.go @@ -0,0 +1,30 @@ +package go_colorhash + +import ( + "testing" +) + +func TestHashBytes(t *testing.T) { + testBytes := []struct { + runAsUser bool + }{} + _ = testBytes +} +func TestHashString(t *testing.T) { + testStrings := []struct { + String string + Value int + ID string + }{{String: "", Value: 7602086723416769149, ID: "Empty string"}, + {String: "123", Value: 1606385479620709231, ID: "123"}, + {String: "it's as easy as", Value: 5377981271559288604, ID: "easy"}, + {String: "hello colorhash", Value: 4155814819593785823, ID: "hello"}} + for _, tc := range testStrings { + t.Run(tc.ID, func(t *testing.T) { + hash := HashString(tc.String) + if hash != tc.Value { + t.Errorf("%s :: Hash resulted in value %d, but expected value is %d", tc.ID, hash, tc.Value) + } + }) + } +}