diff --git a/coding/hex.go b/coding/hex.go new file mode 100644 index 0000000..e75dccf --- /dev/null +++ b/coding/hex.go @@ -0,0 +1,37 @@ +package coding + +import ( + "encoding/hex" + "fmt" + "strings" +) + +func DecodeHex(in string) ([]byte, error) { + normalized := in + if strings.HasPrefix(in, "0x") || strings.HasPrefix(in, "0X") { + normalized = normalized[2:] + } + + return hex.DecodeString(normalized) +} + +func NormalizeBytesToHex(input []byte) string { + return strings.ToLower("0x" + hex.EncodeToString(input)) +} + +// PayloadFingerprint pretty prints a hex payload in an identifiable and succint way. +func PayloadFingerprint(payload []byte) string { + if len(payload) == 0 { + return NormalizeMaybeEmptyBytes(payload) + } + + return fmt.Sprintf("[%s...%s]", hex.EncodeToString(payload[0:4]), hex.EncodeToString(payload[len(payload)-4:])) +} + +// Returns an empty byte slice rather than no output for empty byte arrays +func NormalizeMaybeEmptyBytes(bytes []byte) string { + if len(bytes) > 0 { + return hex.EncodeToString(bytes) + } + return "[]" +} diff --git a/coding/hex_test.go b/coding/hex_test.go new file mode 100644 index 0000000..a7b9df5 --- /dev/null +++ b/coding/hex_test.go @@ -0,0 +1,32 @@ +package coding_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tessellated-io/pickaxe/coding" +) + +func TestDecodeHex(t *testing.T) { + expected := []byte{0x01, 0x02, 0x03, 0x04, 0xa, 0xb} + + cases := []string{ + "010203040a0b", + "0x010203040a0b", + "0X010203040A0B", + } + + for _, in := range cases { + decoded, err := coding.DecodeHex(in) + assert.Nil(t, err, "should not have an error") + assert.Equal(t, expected, decoded, "unexpected decoded value") + } +} + +func TestNormalizeHex(t *testing.T) { + input := []byte{0x00, 0x01, 0x10, 0x11} + + normalized := coding.NormalizeBytesToHex(input) + + assert.Equal(t, "0x00011011", normalized) +}