44 Commits

Author SHA1 Message Date
Kevin Atkinson
caebba6233 gx publish 0.2.7 2018-07-27 17:34:30 -04:00
Kevin Atkinson
83915a874d Merge pull request #21 from multiformats/kevina/map
Enhance Multibase
2018-07-27 17:29:59 -04:00
Steven Allen
03643c33f5 ci: bump minimum go version 2018-07-27 17:02:59 -04:00
Kevin Atkinson
2eb83a994b Remove "magical" NewPrefix function, rename Prefix to Encoder. 2018-07-27 17:02:59 -04:00
Kevin Atkinson
5547437445 Enhance constructor for Prefix type. 2018-07-27 16:59:07 -04:00
Kevin Atkinson
a0557075ec Add prefix type that guarantees a valid multibase prefix. 2018-07-27 16:59:07 -04:00
Kevin Atkinson
3ea5c212ef Add maps for converting from the string repr. to the code and back. 2018-07-27 16:59:01 -04:00
Steven Allen
dfd5076869 gx publish 0.2.6 2017-12-18 10:32:30 -08:00
Steven Allen
3f064509b3 Merge pull request #20 from multiformats/feat/faster
Switch to a faster base58 library
2017-12-18 18:19:05 +00:00
Steven Allen
23774f6467 add benchmarks 2017-12-18 10:08:13 -08:00
Steven Allen
f61622a056 significantly faster b58
* 8-10x faster round trip.
* only 3 allocations each way.
2017-12-17 18:15:25 -08:00
Steven Allen
54686aabd4 gx publish 0.2.5 2017-08-28 20:11:12 -07:00
Steven Allen
307fbd560c Merge pull request #19 from multiformats/kevina/case-preserving
Make base16 and base32 encodings case preserving
2017-08-28 19:32:25 -07:00
Kevin Atkinson
36e6b228ae Move base16 and base32 specific bits to their own file. 2017-08-28 21:33:06 -04:00
Kevin Atkinson
e81eb6473b Change length of test string to encode
to distinguish between padded and unpadded base32 encodings.
2017-08-28 21:33:06 -04:00
Kevin Atkinson
e98e07ec91 Make base16 encoding case preserving. 2017-08-28 21:33:06 -04:00
Kevin Atkinson
8d1441db4b Make base32 encodings case preserving. 2017-08-28 21:33:06 -04:00
Kevin Atkinson
5e86107a34 Update base32 dep. and bump go version to 1.8.3 in CI tests. 2017-08-28 21:32:51 -04:00
Jeromy
af68ad2dd7 gx publish 0.2.4 2017-05-01 17:33:12 -07:00
Jeromy
b3341b58aa Add in base64 raw encodings 2017-04-19 18:02:57 -07:00
Jakub Sztandera
81ab0b304e Merge pull request #13 from multiformats/kevina/multibase-conv
Add simple utility to convert from one base to another.
2017-03-18 00:22:41 +01:00
Jakub Sztandera
2de609b735 Merge pull request #15 from multiformats/docs-improvements
README/golint: improve readme and make golint happy
2017-03-17 18:57:48 +01:00
Jakub Sztandera
67ee8b7fc0 address CR 2017-03-17 18:47:36 +01:00
Hector Sanjuan
d74f4f4a44 README/golint: improve readme and make golint happy
License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
2017-03-17 16:34:42 +01:00
Jakub Sztandera
8cb3334d95 Add streaming to multibase-conv 2017-03-17 15:39:31 +01:00
Kevin Atkinson
7e9a23df22 Add simple utility to convert from one base to another. 2017-03-17 15:35:26 +01:00
Jakub Sztandera
158b7d8e3c ci: fixup coverage collection 2017-03-17 15:35:26 +01:00
Jeromy
a20e296ca7 gx publish 0.2.3 2017-02-02 18:59:19 -08:00
Jeromy
a723c120b9 release 0.2.2 2017-02-02 18:24:17 -08:00
Jakub Sztandera
4cedb5a79e Merge pull request #12 from multiformats/feat/standardize-readme
Edited Badges, small edits
2016-12-26 21:55:11 +01:00
Richard Littauer
6a1554bbad Edited Badges, small edits
Added Travis, CodeCov, Standard Readme, project badge, fixed https links, made description match repo, fixed maintainers title, added year to license.
2016-12-26 15:47:58 -05:00
Jeromy Johnson
9a56b2b802 Merge pull request #10 from multiformats/feat/add-base-null
Implement Identity encoding
2016-12-25 03:02:04 -08:00
Wigy
374a93370a Implement Identity encoding 2016-12-22 17:16:05 +01:00
Jakub Sztandera
c264cdd0ae Use custom Encoding type
Previously base variable were having type `int` which could be confusing
as with literal base number (16 for hex).

By using custom base variable I hope to make it more clear than it was
before.
2016-12-21 20:42:49 +01:00
Jakub Sztandera
e11767a490 Merge pull request #8 from multiformats/feat/ci
Fix CI
2016-12-17 00:01:35 +01:00
Jakub Sztandera
c4f49cd356 codecov: diable comments 2016-12-16 23:56:46 +01:00
Jakub Sztandera
3b16e9048c Fix CI 2016-12-16 23:54:26 +01:00
Jeromy Johnson
ee1176c739 Merge pull request #5 from mateon1/master
Add support for more base encodings
2016-12-16 14:45:06 -08:00
mateon1
8e28da0e2a Updated codes to values from csv, added padded b32
License: MIT
Signed-off-by: Mateusz Naściszewski <matin1111@wp.pl>
2016-12-12 09:01:18 +01:00
mateon1
3d3cb9341e Added support for more base encodings
License: MIT
Signed-off-by: Mateusz Naściszewski <matin1111@wp.pl>
2016-11-27 23:56:23 +01:00
Jeromy
64b00b0f1a gx publish v0.2.1 2016-10-24 15:32:13 -07:00
Jeromy
ed7d4b3b12 guard against empty strings 2016-10-24 15:31:20 -07:00
Jeromy Johnson
2c9be8ec36 Merge pull request #4 from multiformats/feat/license-and-doc
Add license and standardize README
2016-10-14 10:54:33 -04:00
Richard Littauer
528883f051 Add license and standardize README
Still needs Usage section. I wasnt able to see this on godoc.org; how do I publish the godoc? Also, the license needs to be checked. This will close #3
2016-10-14 10:53:31 -04:00
14 changed files with 578 additions and 42 deletions

1
.codecov.yml Normal file
View File

@@ -0,0 +1 @@
comment: off

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
*.swp
multibase-conv/multibase-conv

View File

@@ -1 +1 @@
0.2.0: QmYiTi9mKBMjfiup7na7PhJK7QEZPdMTJenLdgFYVQ2NUv
0.2.7: QmSbvata2WqNkqGtZNg8MR3SKwnB8iQ7vTPJgWqB8bC5kR

25
.travis.yml Normal file
View File

@@ -0,0 +1,25 @@
os:
- linux
language: go
go:
- 1.10.2
install:
- go get -u github.com/whyrusleeping/gx
- go get -u github.com/whyrusleeping/gx-go
- gx install
script:
- gx-go rewrite
- go test -race -coverprofile=unittest.coverprofile -covermode=atomic .
after_success:
- bash <(curl -s https://codecov.io/bash) -f unittest.coverprofile -F unittest
cache:
directories:
- $GOPATH/src/gx

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Protocol Labs Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,7 +1,53 @@
go-multibase
==============
# go-multibase
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs)
[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
[![Travis CI](https://img.shields.io/travis/multiformats/go-multibase.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-multibase)
[![codecov.io](https://img.shields.io/codecov/c/github/multiformats/go-multibase.svg?style=flat-square&branch=master)](https://codecov.io/github/multiformats/go-multibase?branch=master)
> Go implementation of the [multibase](https://github.com/multiformats/multibase) specification.
> Implementation of [multibase](https://github.com/multiformats/multibase) -self identifying base encodings- in Go.
## Install
`go-multibase` is a standard Go module which can be installed with:
```sh
go get github.com/multiformats/go-multibase
```
Note that `go-multibase` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section).
## Usage
This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project it is recommended that you:
```sh
go get -u github.com/whyrusleeping/gx
go get -u github.com/whyrusleeping/gx-go
cd <your-project-repository>
gx init
gx import github.com/multiformats/go-multibase
gx install --global
gx-go --rewrite
```
Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information.
## Maintainers
Captain: [@whyrusleeping](https://github.com/whyrusleeping).
## Contribute
Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multibase/issues).
Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
## License
[MIT](LICENSE) © 2016 Protocol Labs Inc.

21
base16.go Normal file
View File

@@ -0,0 +1,21 @@
package multibase
func hexEncodeToStringUpper(src []byte) string {
dst := make([]byte, len(src)*2)
hexEncodeUpper(dst, src)
return string(dst)
}
var hextableUpper = [16]byte{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F',
}
func hexEncodeUpper(dst, src []byte) int {
for i, v := range src {
dst[i*2] = hextableUpper[v>>4]
dst[i*2+1] = hextableUpper[v&0x0f]
}
return len(src) * 2
}

17
base32.go Normal file
View File

@@ -0,0 +1,17 @@
package multibase
import (
b32 "github.com/whyrusleeping/base32"
)
var base32StdLowerPad = b32.NewEncodingCI("abcdefghijklmnopqrstuvwxyz234567")
var base32StdLowerNoPad = base32StdLowerPad.WithPadding(b32.NoPadding)
var base32StdUpperPad = b32.NewEncodingCI("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")
var base32StdUpperNoPad = base32StdUpperPad.WithPadding(b32.NoPadding)
var base32HexLowerPad = b32.NewEncodingCI("0123456789abcdefghijklmnopqrstuv")
var base32HexLowerNoPad = base32HexLowerPad.WithPadding(b32.NoPadding)
var base32HexUpperPad = b32.NewEncodingCI("0123456789ABCDEFGHIJKLMNOPQRSTUV")
var base32HexUpperNoPad = base32HexUpperPad.WithPadding(b32.NoPadding)

53
encoder.go Normal file
View File

@@ -0,0 +1,53 @@
package multibase
import (
"fmt"
)
// Encoder is a multibase encoding that is verified to be supported and
// supports an Encode method that does not return an error
type Encoder struct {
enc Encoding
}
// NewEncoder create a new Encoder from an Encoding
func NewEncoder(base Encoding) (Encoder, error) {
_, ok := EncodingToStr[base]
if !ok {
return Encoder{-1}, fmt.Errorf("Unsupported multibase encoding: %d", base)
}
return Encoder{base}, nil
}
// EncoderByName creates an encoder from a string, the string can
// either be the multibase name or single character multibase prefix
func EncoderByName(str string) (Encoder, error) {
var base Encoding
ok := true
if len(str) == 0 {
return Encoder{-1}, fmt.Errorf("Empty multibase encoding")
} else if len(str) == 1 {
base = Encoding(str[0])
_, ok = EncodingToStr[base]
} else {
base, ok = Encodings[str]
}
if !ok {
return Encoder{-1}, fmt.Errorf("Unsupported multibase encoding: %s", str)
}
return Encoder{base}, nil
}
func (p Encoder) Encoding() Encoding {
return p.enc
}
// Encode encodes the multibase using the given Encoder.
func (p Encoder) Encode(data []byte) string {
str, err := Encode(p.enc, data)
if err != nil {
// should not happen
panic(err)
}
return str
}

33
encoder_test.go Normal file
View File

@@ -0,0 +1,33 @@
package multibase
import (
"testing"
)
func TestInvalidPrefix(t *testing.T) {
_, err := NewEncoder('q')
if err == nil {
t.Error("expected failure")
}
}
func TestPrefix(t *testing.T) {
for str, base := range Encodings {
prefix, err := NewEncoder(base)
if err != nil {
t.Fatalf("NewEncoder(%c) failed: %v", base, err)
}
str1, err := Encode(base, sampleBytes)
if err != nil {
t.Fatal(err)
}
str2 := prefix.Encode(sampleBytes)
if str1 != str2 {
t.Errorf("encoded string mismatch: %s != %s", str1, str2)
}
_, err = EncoderByName(str)
if err != nil {
t.Fatalf("NewEncoder(%s) failed: %v", str, err)
}
}
}

41
multibase-conv/main.go Normal file
View File

@@ -0,0 +1,41 @@
package main
import (
"fmt"
"os"
multibase "github.com/multiformats/go-multibase"
)
func main() {
if len(os.Args) < 3 {
fmt.Printf("usage: %s <new-base> <multibase-str>...\n", os.Args[0])
os.Exit(1)
}
var newBase multibase.Encoding
if baseParm := os.Args[1]; len(baseParm) != 0 {
newBase = multibase.Encoding(baseParm[0])
} else {
fmt.Fprintln(os.Stderr, "<new-base> is empty")
os.Exit(1)
}
input := os.Args[2:]
for _, strmbase := range input {
_, data, err := multibase.Decode(strmbase)
if err != nil {
fmt.Fprintf(os.Stderr, "error while decoding: %s\n", err)
os.Exit(1)
}
newCid, err := multibase.Encode(newBase, data)
if err != nil {
fmt.Fprintf(os.Stderr, "error while encoding: %s\n", err)
os.Exit(1)
}
fmt.Println(newCid)
}
}

View File

@@ -1,39 +1,179 @@
package multibase
import (
"encoding/base64"
"encoding/hex"
"fmt"
b58 "github.com/jbenet/go-base58"
b58 "github.com/mr-tron/base58/base58"
b32 "github.com/whyrusleeping/base32"
)
// 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 (
Base1 = '1'
Base2 = '0'
Base8 = '7'
Base10 = '9'
Base16 = 'f'
Base58Flickr = 'Z'
Base58BTC = 'z'
Identity = 0x00
Base1 = '1'
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'
Base58Flickr = 'Z'
Base58BTC = 'z'
Base64 = 'm'
Base64url = 'u'
Base64pad = 'M'
Base64urlPad = 'U'
)
// Encodigs is a map of the supported encoding, unsupported encoding
// specified in standard are left out
var Encodings = map[string]Encoding{
"identity": 0x00,
"base16": 'f',
"base16upper": 'F',
"base32": 'b',
"base32upper": 'B',
"base32pad": 'c',
"base32padupper": 'C',
"base32hex": 'v',
"base32hexupper": 'V',
"base32hexpad": 't',
"base32hexpadupper": 'T',
"base58flickr": 'Z',
"base58btc": 'z',
"base64": 'm',
"base64url": 'u',
"base64pad": 'M',
"base64urlpad": 'U',
}
var EncodingToStr = map[Encoding]string{
0x00: "identity",
'f': "base16",
'F': "base16upper",
'b': "base32",
'B': "base32upper",
'c': "base32pad",
'C': "base32padupper",
'v': "base32hex",
'V': "base32hexupper",
't': "base32hexpad",
'T': "base32hexpadupper",
'Z': "base58flickr",
'z': "base58btc",
'm': "base64",
'u': "base64url",
'M': "base64pad",
'U': "base64urlpad",
}
// ErrUnsupportedEncoding is returned when the selected encoding is not known or
// implemented.
var ErrUnsupportedEncoding = fmt.Errorf("selected encoding not supported")
func Encode(base int, data []byte) (string, error) {
// 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 Base58BTC:
return string(Base58BTC) + b58.EncodeAlphabet(data, b58.BTCAlphabet), nil
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:
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 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
default:
return "", ErrUnsupportedEncoding
}
}
func Decode(data string) (int, []byte, error) {
switch data[0] {
// 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")
}
enc := Encoding(data[0])
switch enc {
case Identity:
return Identity, []byte(data[1:]), nil
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 Base58BTC:
return Base58BTC, b58.DecodeAlphabet(data[1:], b58.BTCAlphabet), nil
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
default:
return -1, nil, ErrUnsupportedEncoding
}

View File

@@ -6,25 +6,154 @@ import (
"testing"
)
func TestBase58RoundTrip(t *testing.T) {
buf := make([]byte, 16)
rand.Read(buf)
enc, err := Encode(Base58BTC, buf)
if err != nil {
t.Fatal(err)
func TestMap(t *testing.T) {
for s,e := range Encodings {
s2 := EncodingToStr[e]
if s != s2 {
t.Errorf("round trip failed on encoding map: %s != %s", s, s2)
}
}
e, out, err := Decode(enc)
if err != nil {
t.Fatal(err)
}
if e != Base58BTC {
t.Fatal("got wrong encoding out")
}
if !bytes.Equal(buf, out) {
t.Fatal("input wasnt the same as output", buf, out)
for e,s := range EncodingToStr {
e2 := Encodings[s]
if e != e2 {
t.Errorf("round trip failed on encoding map: '%c' != '%c'", e, e2)
}
}
}
var sampleBytes = []byte("Decentralize everything!!!")
var encodedSamples = map[Encoding]string{
Identity: string(0x00) + "Decentralize everything!!!",
Base16: "f446563656e7472616c697a652065766572797468696e67212121",
Base16Upper: "F446563656E7472616C697A652065766572797468696E67212121",
Base32: "birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijbee",
Base32Upper: "BIRSWGZLOORZGC3DJPJSSAZLWMVZHS5DINFXGOIJBEE",
Base32pad: "cirswgzloorzgc3djpjssazlwmvzhs5dinfxgoijbee======",
Base32padUpper: "CIRSWGZLOORZGC3DJPJSSAZLWMVZHS5DINFXGOIJBEE======",
Base32hex: "v8him6pbeehp62r39f9ii0pbmclp7it38d5n6e89144",
Base32hexUpper: "V8HIM6PBEEHP62R39F9II0PBMCLP7IT38D5N6E89144",
Base32hexPad: "t8him6pbeehp62r39f9ii0pbmclp7it38d5n6e89144======",
Base32hexPadUpper: "T8HIM6PBEEHP62R39F9II0PBMCLP7IT38D5N6E89144======",
Base58BTC: "z36UQrhJq9fNDS7DiAHM9YXqDHMPfr4EMArvt",
Base64pad: "MRGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE=",
Base64urlPad: "URGVjZW50cmFsaXplIGV2ZXJ5dGhpbmchISE=",
}
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, 17)
rand.Read(buf)
baseList := []Encoding{Identity, Base16, Base32, Base32hex, Base32pad, Base32hexPad, Base58BTC, Base58Flickr, Base64pad, Base64urlPad}
for _, base := range baseList {
enc, err := Encode(base, buf)
if err != nil {
t.Fatal(err)
}
e, out, err := Decode(enc)
if err != nil {
t.Fatal(err)
}
if e != base {
t.Fatal("got wrong encoding out")
}
if !bytes.Equal(buf, out) {
t.Fatal("input wasnt the same as output", buf, out)
}
}
_, _, err := Decode("")
if err == nil {
t.Fatal("shouldnt be able to decode empty string")
}
}
func BenchmarkRoundTrip(b *testing.B) {
buf := make([]byte, 32)
rand.Read(buf)
b.ResetTimer()
bases := map[string]Encoding{
"Identity": Identity,
"Base16": Base16,
"Base16Upper": Base16Upper,
"Base32": Base32,
"Base32Upper": Base32Upper,
"Base32pad": Base32pad,
"Base32padUpper": Base32padUpper,
"Base32hex": Base32hex,
"Base32hexUpper": Base32hexUpper,
"Base32hexPad": Base32hexPad,
"Base32hexPadUpper": Base32hexPadUpper,
"Base58Flickr": Base58Flickr,
"Base58BTC": Base58BTC,
"Base64": Base64,
"Base64url": Base64url,
"Base64pad": Base64pad,
"Base64urlPad": Base64urlPad,
}
for name, base := range bases {
b.Run(name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
enc, err := Encode(base, buf)
if err != nil {
b.Fatal(err)
}
e, out, err := Decode(enc)
if err != nil {
b.Fatal(err)
}
if e != base {
b.Fatal("got wrong encoding out")
}
if !bytes.Equal(buf, out) {
b.Fatal("input wasnt the same as output", buf, out)
}
}
})
}
}

View File

@@ -9,14 +9,22 @@
"gxDependencies": [
{
"author": "whyrusleeping",
"hash": "QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf",
"name": "go-base58",
"version": "0.0.0"
"hash": "QmfVj3x4D6Jkq9SEoi5n2NmoUomLwoeiwnYz2KQa15wRw6",
"name": "base32",
"version": "0.0.2"
},
{
"author": "mr-tron",
"hash": "QmWFAMPqsEyUX7gDUsRVmMWz59FxSpJ1b2v6bJ1yYzo7jY",
"name": "go-base58-fast",
"version": "0.1.1"
}
],
"gxVersion": "0.8.0",
"language": "go",
"license": "",
"name": "go-multibase",
"version": "0.2.0"
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "0.2.7"
}