commit c5b43ef4082cff710b3d6cdfb67dcf671d523d92 Author: blinkthethings Date: Thu Dec 24 11:12:28 2020 -0500 Initial commit diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b747313 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.trashheap.io/blinkthethings/modhex + +go 1.15 diff --git a/modhex.go b/modhex.go new file mode 100644 index 0000000..fc0cf37 --- /dev/null +++ b/modhex.go @@ -0,0 +1,66 @@ +package modhex + +import ( + "errors" + "fmt" +) + +const hexChars = "0123456789abcdef" +const modhexChars = "cbdefghijklnrtuv" + +var modhex2HexMap map[byte]byte +var hex2ModhexMap map[byte]byte + +func init() { + hex2ModhexMap = make(map[byte]byte) + for i, h := range []byte(hexChars) { + hex2ModhexMap[h] = modhexChars[i] + } + + modhex2HexMap = make(map[byte]byte) + for i, m := range []byte(modhexChars) { + modhex2HexMap[m] = hexChars[i] + } +} + +// EncodeHex encodes a hex string into a modhex string +func EncodeHex(hex string) (string, error) { + size := len([]byte(hex)) + + if size%2 == 1 { + return "", errors.New("size of input hex input not even") + } + + var modhex = make([]byte, size) + + for i, h := range []byte(hex) { + if m, ok := hex2ModhexMap[h]; ok { + modhex[i] = m + } else { + return "", fmt.Errorf("input not hex encoded; position %d", i) + } + } + + return string(modhex), nil +} + +// DecodeHex decodes a modhex string into a hex string +func DecodeHex(modhex string) (string, error) { + size := len([]byte(modhex)) + + if size%2 == 1 { + return "", errors.New("size of modhex input not even") + } + + var hex = make([]byte, size) + + for i, m := range []byte(modhex) { + if h, ok := modhex2HexMap[m]; ok { + hex[i] = h + } else { + return "", fmt.Errorf("input not modhex encoded; position %d", i) + } + } + + return string(hex), nil +} diff --git a/modhex_test.go b/modhex_test.go new file mode 100644 index 0000000..ed1e839 --- /dev/null +++ b/modhex_test.go @@ -0,0 +1,49 @@ +package modhex + +import "testing" + +type test struct { + hex string + modhex string +} + +func TestEncodeHexDecodeHex(t *testing.T) { + var tests = []test{ + { + modhex: "dteffuje", + hex: "2d344e83", + }, + + { + modhex: "hknhfjbrjnlnldnhcujvddbikngjrtgh", + hex: "69b6481c8baba2b60e8f22179b58cd56", + }, + + { + modhex: "urtubjtnuihvntcreeeecvbregfjibtn", + hex: "ecde18dbe76fbd0c33330f1c354871db", + }, + } + + for _, tc := range tests { + modhex, err := EncodeHex(tc.hex) + + if err != nil { + t.Errorf("EncodeHex Error: %s\n", err) + } + + if modhex != tc.modhex { + t.Errorf("EncodeHex Incorrect: Actual: %s; Expected: %s\n", modhex, tc.modhex) + } + + hex, err := DecodeHex(tc.modhex) + + if err != nil { + t.Errorf("DecodeHex Error: %s\n", err) + } + + if hex != tc.hex { + t.Errorf("DecodeHex Incorrect: Actual: %s; Expected: %s\n", hex, tc.hex) + } + } +}