From 374a93370a0a8397d37caa4a50b13f85166b5310 Mon Sep 17 00:00:00 2001 From: Wigy Date: Mon, 19 Dec 2016 14:34:26 +0100 Subject: [PATCH] Implement Identity encoding --- multibase.go | 6 ++++++ multibase_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/multibase.go b/multibase.go index 239acf8..9746737 100644 --- a/multibase.go +++ b/multibase.go @@ -12,6 +12,7 @@ import ( type Encoding int const ( + Identity = 0x00 Base1 = '1' Base2 = '0' Base8 = '7' @@ -38,6 +39,9 @@ var ErrUnsupportedEncoding = fmt.Errorf("selected encoding not supported") func Encode(base Encoding, data []byte) (string, error) { switch base { + case Identity: + // 0x00 inside a string is OK in golang and causes no problems with the length calculation. + return string(Identity) + string(data), nil case Base16, Base16Upper: return string(Base16) + hex.EncodeToString(data), nil case Base32, Base32Upper: @@ -67,6 +71,8 @@ func Decode(data string) (Encoding, []byte, error) { } switch data[0] { + case Identity: + return Identity, []byte(data[1:]), nil case Base16, Base16Upper: bytes, err := hex.DecodeString(data[1:]) return Base16, bytes, err diff --git a/multibase_test.go b/multibase_test.go index a086633..e71f77f 100644 --- a/multibase_test.go +++ b/multibase_test.go @@ -6,11 +6,57 @@ import ( "testing" ) +var sampleBytes = []byte("Decentralize everything!!") +var encodedSamples = map[Encoding]string{ + Identity: string(0x00) + "Decentralize everything!!", + Base16: "f446563656e7472616c697a652065766572797468696e672121", + Base58BTC: "zUXE7GvtEk8XTXs1GF8HSGbVA9FCX9SEBPe", + Base64pad: "MRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchIQ==", + Base64urlPad: "URGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchIQ==", +} + +func testEncode(t *testing.T, encoding Encoding, bytes []byte, expected string) { + actual, err := Encode(encoding, bytes) + if err != nil { + t.Error(err) + return + } + if actual != expected { + t.Errorf("encoding failed for %c (%d), expected: %s, got: %s", encoding, encoding, expected, actual) + } +} + +func testDecode(t *testing.T, expectedEncoding Encoding, expectedBytes []byte, data string) { + actualEncoding, actualBytes, err := Decode(data) + if err != nil { + t.Error(err) + return + } + if actualEncoding != expectedEncoding { + t.Errorf("wrong encoding code, expected: %c (%d), got %c (%d)", expectedEncoding, expectedEncoding, actualEncoding, actualEncoding) + } + if !bytes.Equal(actualBytes, expectedBytes) { + t.Errorf("decoding failed for %c (%d), expected: %v, got %v", actualEncoding, actualEncoding, expectedBytes, actualBytes) + } +} + +func TestEncode(t *testing.T) { + for encoding, data := range encodedSamples { + testEncode(t, encoding, sampleBytes, data) + } +} + +func TestDecode(t *testing.T) { + for encoding, data := range encodedSamples { + testDecode(t, encoding, sampleBytes, data) + } +} + func TestRoundTrip(t *testing.T) { - buf := make([]byte, 16) + buf := make([]byte, 17) rand.Read(buf) - baseList := []Encoding{Base16, Base32, Base32hex, Base32pad, Base32hexPad, Base58BTC, Base58Flickr, Base64pad, Base64urlPad} + baseList := []Encoding{Identity, Base16, Base32, Base32hex, Base32pad, Base32hexPad, Base58BTC, Base58Flickr, Base64pad, Base64urlPad} for _, base := range baseList { enc, err := Encode(base, buf)