diff --git a/cid.go b/cid.go index 67e263d..2c4af4f 100644 --- a/cid.go +++ b/cid.go @@ -47,6 +47,10 @@ var ( // ErrCidTooShort means that the cid passed to decode was not long // enough to be a valid Cid ErrCidTooShort = errors.New("cid too short") + + // ErrInvalidEncoding means that selected encoding is not supported + // by this Cid version + ErrInvalidEncoding = errors.New("invalid base encoding") ) // These are multicodec-packed content types. The should match @@ -247,6 +251,22 @@ func (c *Cid) String() string { } } +// String returns the string representation of a Cid +// encoded is selected base +func (c *Cid) StringOfBase(base mbase.Encoding) (string, error) { + switch c.version { + case 0: + if base != mbase.Base58BTC { + return "", ErrInvalidEncoding + } + return c.hash.B58String(), nil + case 1: + return mbase.Encode(base, c.bytesV1()) + default: + panic("not possible to reach this point") + } +} + // Hash returns the multihash contained by a Cid. func (c *Cid) Hash() mh.Multihash { return c.hash diff --git a/cid_test.go b/cid_test.go index 5bf7a52..82abfa3 100644 --- a/cid_test.go +++ b/cid_test.go @@ -8,6 +8,7 @@ import ( "strings" "testing" + mbase "github.com/multiformats/go-multibase" mh "github.com/multiformats/go-multihash" ) @@ -55,6 +56,60 @@ func TestBasicMarshaling(t *testing.T) { assertEqual(t, cid, out2) } +func TestBasesMarshaling(t *testing.T) { + h, err := mh.Sum([]byte("TEST"), mh.SHA3, 4) + if err != nil { + t.Fatal(err) + } + + cid := &Cid{ + codec: 7, + version: 1, + hash: h, + } + + data := cid.Bytes() + + out, err := Cast(data) + if err != nil { + t.Fatal(err) + } + + assertEqual(t, cid, out) + + testBases := []mbase.Encoding { + mbase.Base16, + mbase.Base32, + mbase.Base32hex, + mbase.Base32pad, + mbase.Base32hexPad, + mbase.Base58BTC, + mbase.Base58Flickr, + mbase.Base64pad, + mbase.Base64urlPad, + mbase.Base64url, + mbase.Base64, + } + + for _, b := range testBases { + s, err := cid.StringOfBase(b) + if err != nil { + t.Fatal(err) + } + + if s[0] != byte(b) { + t.Fatal("Invalid multibase header") + } + + out2, err := Decode(s) + if err != nil { + t.Fatal(err) + } + + assertEqual(t, cid, out2) + } +} + func TestEmptyString(t *testing.T) { _, err := Decode("") if err == nil {