status-go/vendor/github.com/multiformats/go-multibase/multibase.go

195 lines
6.1 KiB
Go
Raw Normal View History

2019-06-09 07:24:20 +00:00
package multibase
import (
"encoding/base64"
"encoding/hex"
"fmt"
"unicode/utf8"
2019-06-09 07:24:20 +00:00
b58 "github.com/mr-tron/base58/base58"
b32 "github.com/multiformats/go-base32"
b36 "github.com/multiformats/go-base36"
2019-06-09 07:24:20 +00:00
)
// Encoding identifies the type of base-encoding that a multibase is carrying.
type Encoding int
// These are the encodings specified in the standard, not are all
// supported yet
const (
Identity = 0x00
Base2 = '0'
Base8 = '7'
Base10 = '9'
Base16 = 'f'
Base16Upper = 'F'
Base32 = 'b'
Base32Upper = 'B'
Base32pad = 'c'
Base32padUpper = 'C'
Base32hex = 'v'
Base32hexUpper = 'V'
Base32hexPad = 't'
Base32hexPadUpper = 'T'
Base36 = 'k'
Base36Upper = 'K'
2019-06-09 07:24:20 +00:00
Base58BTC = 'z'
Base58Flickr = 'Z'
2019-06-09 07:24:20 +00:00
Base64 = 'm'
Base64url = 'u'
Base64pad = 'M'
Base64urlPad = 'U'
Base256Emoji = '🚀'
2019-06-09 07:24:20 +00:00
)
// EncodingToStr is a map of the supported encoding, unsupported encoding
2019-06-09 07:24:20 +00:00
// specified in standard are left out
var EncodingToStr = map[Encoding]string{
0x00: "identity",
'0': "base2",
'f': "base16",
'F': "base16upper",
'b': "base32",
'B': "base32upper",
'c': "base32pad",
'C': "base32padupper",
'v': "base32hex",
'V': "base32hexupper",
't': "base32hexpad",
'T': "base32hexpadupper",
'k': "base36",
'K': "base36upper",
'z': "base58btc",
'Z': "base58flickr",
'm': "base64",
'u': "base64url",
'M': "base64pad",
'U': "base64urlpad",
Base256Emoji: "base256emoji",
2019-06-09 07:24:20 +00:00
}
var Encodings = map[string]Encoding{}
func init() {
for e, n := range EncodingToStr {
Encodings[n] = e
}
}
2019-06-09 07:24:20 +00:00
// ErrUnsupportedEncoding is returned when the selected encoding is not known or
// implemented.
var ErrUnsupportedEncoding = fmt.Errorf("selected encoding not supported")
// Encode encodes a given byte slice with the selected encoding and returns a
// multibase string (<encoding><base-encoded-string>). It will return
// an error if the selected base is not known.
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(rune(Identity)) + string(data), nil
2019-06-09 07:24:20 +00:00
case Base2:
return string(Base2) + binaryEncodeToString(data), nil
case Base16:
return string(Base16) + hex.EncodeToString(data), nil
case Base16Upper:
return string(Base16Upper) + hexEncodeToStringUpper(data), nil
case Base32:
return string(Base32) + base32StdLowerNoPad.EncodeToString(data), nil
case Base32Upper:
return string(Base32Upper) + base32StdUpperNoPad.EncodeToString(data), nil
case Base32hex:
return string(Base32hex) + base32HexLowerNoPad.EncodeToString(data), nil
case Base32hexUpper:
return string(Base32hexUpper) + base32HexUpperNoPad.EncodeToString(data), nil
case Base32pad:
return string(Base32pad) + base32StdLowerPad.EncodeToString(data), nil
case Base32padUpper:
return string(Base32padUpper) + base32StdUpperPad.EncodeToString(data), nil
case Base32hexPad:
return string(Base32hexPad) + base32HexLowerPad.EncodeToString(data), nil
case Base32hexPadUpper:
return string(Base32hexPadUpper) + base32HexUpperPad.EncodeToString(data), nil
case Base36:
return string(Base36) + b36.EncodeToStringLc(data), nil
case Base36Upper:
return string(Base36Upper) + b36.EncodeToStringUc(data), nil
2019-06-09 07:24:20 +00:00
case Base58BTC:
return string(Base58BTC) + b58.EncodeAlphabet(data, b58.BTCAlphabet), nil
case Base58Flickr:
return string(Base58Flickr) + b58.EncodeAlphabet(data, b58.FlickrAlphabet), nil
case Base64pad:
return string(Base64pad) + base64.StdEncoding.EncodeToString(data), nil
case Base64urlPad:
return string(Base64urlPad) + base64.URLEncoding.EncodeToString(data), nil
case Base64url:
return string(Base64url) + base64.RawURLEncoding.EncodeToString(data), nil
case Base64:
return string(Base64) + base64.RawStdEncoding.EncodeToString(data), nil
case Base256Emoji:
return string(Base256Emoji) + base256emojiEncode(data), nil
2019-06-09 07:24:20 +00:00
default:
return "", ErrUnsupportedEncoding
}
}
// Decode takes a multibase string and decodes into a bytes buffer.
// It will return an error if the selected base is not known.
func Decode(data string) (Encoding, []byte, error) {
if len(data) == 0 {
return 0, nil, fmt.Errorf("cannot decode multibase for zero length string")
}
r, _ := utf8.DecodeRuneInString(data)
enc := Encoding(r)
2019-06-09 07:24:20 +00:00
switch enc {
case Identity:
return Identity, []byte(data[1:]), nil
case Base2:
bytes, err := decodeBinaryString(data[1:])
return enc, bytes, err
case Base16, Base16Upper:
bytes, err := hex.DecodeString(data[1:])
return enc, bytes, err
case Base32, Base32Upper:
bytes, err := b32.RawStdEncoding.DecodeString(data[1:])
return enc, bytes, err
case Base32hex, Base32hexUpper:
bytes, err := b32.RawHexEncoding.DecodeString(data[1:])
return enc, bytes, err
case Base32pad, Base32padUpper:
bytes, err := b32.StdEncoding.DecodeString(data[1:])
return enc, bytes, err
case Base32hexPad, Base32hexPadUpper:
bytes, err := b32.HexEncoding.DecodeString(data[1:])
return enc, bytes, err
case Base36, Base36Upper:
bytes, err := b36.DecodeString(data[1:])
return enc, bytes, err
2019-06-09 07:24:20 +00:00
case Base58BTC:
bytes, err := b58.DecodeAlphabet(data[1:], b58.BTCAlphabet)
return Base58BTC, bytes, err
case Base58Flickr:
bytes, err := b58.DecodeAlphabet(data[1:], b58.FlickrAlphabet)
return Base58Flickr, bytes, err
case Base64pad:
bytes, err := base64.StdEncoding.DecodeString(data[1:])
return Base64pad, bytes, err
case Base64urlPad:
bytes, err := base64.URLEncoding.DecodeString(data[1:])
return Base64urlPad, bytes, err
case Base64:
bytes, err := base64.RawStdEncoding.DecodeString(data[1:])
return Base64, bytes, err
case Base64url:
bytes, err := base64.RawURLEncoding.DecodeString(data[1:])
return Base64url, bytes, err
case Base256Emoji:
bytes, err := base256emojiDecode(data[4:])
return Base256Emoji, bytes, err
2019-06-09 07:24:20 +00:00
default:
return -1, nil, ErrUnsupportedEncoding
}
}