Skip to content

Commit d5e694a

Browse files
authored
Merge pull request #41 from brandoneprice31/hex
Hex
2 parents 44928ed + a2152c4 commit d5e694a

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

hashids.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"errors"
1111
"fmt"
1212
"math"
13+
"strconv"
1314
"strings"
1415
)
1516

@@ -220,6 +221,24 @@ func (h *HashID) EncodeInt64(numbers []int64) (string, error) {
220221
return string(result), nil
221222
}
222223

224+
// EncodeHex hashes a hexadecimal string to a string containing at least MinLength characters taken from the Alphabet.
225+
// A hexadecimal string should not contain the 0x prefix.
226+
// Use DecodeHex using the same Alphabet and Salt to get back the hexadecimal string.
227+
func (h *HashID) EncodeHex(hex string) (string, error) {
228+
chars := []rune(hex)
229+
nums := []int{}
230+
231+
for _, s := range chars {
232+
n, err := strconv.ParseInt(fmt.Sprintf("1%s", string(s)), 16, 64)
233+
if err != nil {
234+
return "", err
235+
}
236+
nums = append(nums, int(n))
237+
}
238+
239+
return h.Encode(nums)
240+
}
241+
223242
// DEPRECATED: Use DecodeWithError instead
224243
// Decode unhashes the string passed to an array of int.
225244
// It is symmetric with Encode if the Alphabet and Salt are the same ones which were used to hash.
@@ -301,6 +320,23 @@ func (h *HashID) DecodeInt64WithError(hash string) ([]int64, error) {
301320
return result, nil
302321
}
303322

323+
// DecodeHex unhashes the string passed to a hexadecimal string.
324+
// It is symmetric with EncodeHex if the Alphabet and Salt are the same ones which were used to hash.
325+
func (h *HashID) DecodeHex(hash string) (string, error) {
326+
numbers, err := h.DecodeInt64WithError(hash)
327+
if err != nil {
328+
return "", err
329+
}
330+
331+
ret := ""
332+
for _, n := range numbers {
333+
nHex := fmt.Sprintf("%X", n)
334+
ret = strings.ToLower(fmt.Sprintf("%s%s", ret, nHex[1:len(nHex)]))
335+
}
336+
337+
return ret, nil
338+
}
339+
304340
func splitRunes(input, seps []rune) [][]rune {
305341
splitIndices := make([]int, 0)
306342
for i, inputRune := range input {

hashids_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,30 @@ func TestEncodeDecodeInt64(t *testing.T) {
4848
}
4949
}
5050

51+
func TestEncodeDecodeHex(t *testing.T) {
52+
hdata := NewData()
53+
hdata.MinLength = 30
54+
hdata.Salt = "this is my salt"
55+
56+
hid, _ := NewWithData(hdata)
57+
hex := "5a74d76ac89b05000e977baa"
58+
59+
hash, err := hid.EncodeHex(hex)
60+
if err != nil {
61+
t.Fatal(err)
62+
}
63+
64+
dec, err := hid.DecodeHex(hash)
65+
if err != nil {
66+
t.Fatal(err)
67+
}
68+
69+
t.Logf("%v -> %v -> %v", hex, hash, dec)
70+
if !reflect.DeepEqual(hex, dec) {
71+
t.Errorf("Decoded hex `%v` did not match with original `%v`", dec, hex)
72+
}
73+
}
74+
5175
func TestEncodeWithKnownHash(t *testing.T) {
5276
hdata := NewData()
5377
hdata.MinLength = 0
@@ -145,7 +169,7 @@ func TestDecodeWithError(t *testing.T) {
145169
dec, err := hid.DecodeWithError("MAkhkloFAxAoskaZ")
146170

147171
if dec != nil {
148-
t.Error("Expected `nil` but got `%v`", dec)
172+
t.Errorf("Expected `nil` but got `%v`", dec)
149173
}
150174
expected := "alphabet used for hash was different"
151175
if err == nil || err.Error() != expected {

0 commit comments

Comments
 (0)