22 Commits

Author SHA1 Message Date
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
9 changed files with 262 additions and 37 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.1: QmUq3H9YpcPphbRj6ct6rBgBE377A8wANP8zPMRqe1WYbf
0.2.4: Qme4T6BE4sQxg7ZouamF5M7Tx1ZFTqzcns7BkyQPXpoT99

25
.travis.yml Normal file
View File

@@ -0,0 +1,25 @@
os:
- linux
language: go
go:
- 1.7
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

View File

@@ -1,21 +1,42 @@
# 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)
> Implementation of [multibase](https://github.com/multiformats/multibase) -self identifying base encodings- in Go.
> Go implementation of the [multibase](https://github.com/multiformats/multibase) specification.
## 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
TODO
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:
## Maintainer
```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).
@@ -29,4 +50,4 @@ Small note: If editing the README, please conform to the [standard-readme](https
## License
[MIT](LICENSE) © Protocol Labs Inc.
[MIT](LICENSE) © 2016 Protocol Labs Inc.

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,43 +1,122 @@
package multibase
import (
"encoding/base64"
"encoding/hex"
"fmt"
b58 "github.com/jbenet/go-base58"
b32 "github.com/whyrusleeping/base32"
)
// Encoding identifies the type of base-encoding that a multibase is carrying.
type Encoding int
// These are the supported encodings
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'
)
// 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 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:
return string(Base32) + b32.RawStdEncoding.EncodeToString(data), nil
case Base32hex, Base32hexUpper:
return string(Base32hex) + b32.RawHexEncoding.EncodeToString(data), nil
case Base32pad, Base32padUpper:
return string(Base32pad) + b32.StdEncoding.EncodeToString(data), nil
case Base32hexPad, Base32hexPadUpper:
return string(Base32hexPad) + b32.HexEncoding.EncodeToString(data), nil
case Base58BTC:
return string(Base58BTC) + b58.EncodeAlphabet(data, b58.BTCAlphabet), nil
case Base16:
return string(Base16) + hex.EncodeToString(data), 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) {
// 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")
}
switch data[0] {
case Identity:
return Identity, []byte(data[1:]), nil
case Base16, Base16Upper:
bytes, err := hex.DecodeString(data[1:])
return Base16, bytes, err
case Base32, Base32Upper:
bytes, err := b32.RawStdEncoding.DecodeString(data[1:])
return Base32, bytes, err
case Base32hex, Base32hexUpper:
bytes, err := b32.RawHexEncoding.DecodeString(data[1:])
return Base32hex, bytes, err
case Base32pad, Base32padUpper:
bytes, err := b32.StdEncoding.DecodeString(data[1:])
return Base32pad, bytes, err
case Base32hexPad, Base32hexPadUpper:
bytes, err := b32.HexEncoding.DecodeString(data[1:])
return Base32hexPad, bytes, err
case Base58BTC:
return Base58BTC, b58.DecodeAlphabet(data[1:], b58.BTCAlphabet), nil
case Base58Flickr:
return Base58Flickr, b58.DecodeAlphabet(data[1:], b58.FlickrAlphabet), nil
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,29 +6,79 @@ import (
"testing"
)
func TestBase58RoundTrip(t *testing.T) {
buf := make([]byte, 16)
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, 17)
rand.Read(buf)
enc, err := Encode(Base58BTC, buf)
if err != nil {
t.Fatal(err)
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)
}
}
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)
}
_, _, err = Decode("")
_, _, err := Decode("")
if err == nil {
t.Fatal("shouldnt be able to decode empty string")
}

View File

@@ -7,6 +7,12 @@
"dvcsimport": "github.com/multiformats/go-multibase"
},
"gxDependencies": [
{
"author": "whyrusleeping",
"hash": "QmZvZSVtvxak4dcTkhsQhqd1SQ6rg5UzaSTu62WfWKjj93",
"name": "base32",
"version": "0.0.1"
},
{
"author": "whyrusleeping",
"hash": "QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf",
@@ -18,6 +24,7 @@
"language": "go",
"license": "",
"name": "go-multibase",
"version": "0.2.1"
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "0.2.4"
}