Merge pull request #28 from gowthamgts/base2
Added base2 implementation as per RFC
This commit is contained in:
52
base2.go
Normal file
52
base2.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package multibase
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// binaryEncodeToString takes an array of bytes and returns
|
||||||
|
// multibase binary representation
|
||||||
|
func binaryEncodeToString(src []byte) string {
|
||||||
|
dst := make([]byte, len(src)*8)
|
||||||
|
encodeBinary(dst, src)
|
||||||
|
return string(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
// encodeBinary takes the src and dst bytes and converts each
|
||||||
|
// byte to their binary rep using power reduction method
|
||||||
|
func encodeBinary(dst []byte, src []byte) {
|
||||||
|
for i, b := range src {
|
||||||
|
for j := 0; j < 8; j++ {
|
||||||
|
if b&(1<<uint(7-j)) == 0 {
|
||||||
|
dst[i*8+j] = '0'
|
||||||
|
} else {
|
||||||
|
dst[i*8+j] = '1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// decodeBinaryString takes multibase binary representation
|
||||||
|
// and returns a byte array
|
||||||
|
func decodeBinaryString(s string) ([]byte, error) {
|
||||||
|
if len(s)&7 != 0 {
|
||||||
|
// prepend the padding
|
||||||
|
s = strings.Repeat("0", 8-len(s)&7) + s
|
||||||
|
}
|
||||||
|
|
||||||
|
data := make([]byte, len(s)>>3)
|
||||||
|
|
||||||
|
for i, dstIndex := 0, 0; i < len(s); i = i + 8 {
|
||||||
|
value, err := strconv.ParseInt(s[i:i+8], 2, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error while conversion: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
data[dstIndex] = byte(value)
|
||||||
|
dstIndex++
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
@@ -42,6 +42,7 @@ const (
|
|||||||
// specified in standard are left out
|
// specified in standard are left out
|
||||||
var Encodings = map[string]Encoding{
|
var Encodings = map[string]Encoding{
|
||||||
"identity": 0x00,
|
"identity": 0x00,
|
||||||
|
"base2": '0',
|
||||||
"base16": 'f',
|
"base16": 'f',
|
||||||
"base16upper": 'F',
|
"base16upper": 'F',
|
||||||
"base32": 'b',
|
"base32": 'b',
|
||||||
@@ -62,6 +63,7 @@ var Encodings = map[string]Encoding{
|
|||||||
|
|
||||||
var EncodingToStr = map[Encoding]string{
|
var EncodingToStr = map[Encoding]string{
|
||||||
0x00: "identity",
|
0x00: "identity",
|
||||||
|
'0': "base2",
|
||||||
'f': "base16",
|
'f': "base16",
|
||||||
'F': "base16upper",
|
'F': "base16upper",
|
||||||
'b': "base32",
|
'b': "base32",
|
||||||
@@ -92,6 +94,8 @@ func Encode(base Encoding, data []byte) (string, error) {
|
|||||||
case Identity:
|
case Identity:
|
||||||
// 0x00 inside a string is OK in golang and causes no problems with the length calculation.
|
// 0x00 inside a string is OK in golang and causes no problems with the length calculation.
|
||||||
return string(Identity) + string(data), nil
|
return string(Identity) + string(data), nil
|
||||||
|
case Base2:
|
||||||
|
return string(Base2) + binaryEncodeToString(data), nil
|
||||||
case Base16:
|
case Base16:
|
||||||
return string(Base16) + hex.EncodeToString(data), nil
|
return string(Base16) + hex.EncodeToString(data), nil
|
||||||
case Base16Upper:
|
case Base16Upper:
|
||||||
@@ -141,6 +145,9 @@ func Decode(data string) (Encoding, []byte, error) {
|
|||||||
switch enc {
|
switch enc {
|
||||||
case Identity:
|
case Identity:
|
||||||
return Identity, []byte(data[1:]), nil
|
return Identity, []byte(data[1:]), nil
|
||||||
|
case Base2:
|
||||||
|
bytes, err := decodeBinaryString(data[1:])
|
||||||
|
return enc, bytes, err
|
||||||
case Base16, Base16Upper:
|
case Base16, Base16Upper:
|
||||||
bytes, err := hex.DecodeString(data[1:])
|
bytes, err := hex.DecodeString(data[1:])
|
||||||
return enc, bytes, err
|
return enc, bytes, err
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ func TestMap(t *testing.T) {
|
|||||||
var sampleBytes = []byte("Decentralize everything!!!")
|
var sampleBytes = []byte("Decentralize everything!!!")
|
||||||
var encodedSamples = map[Encoding]string{
|
var encodedSamples = map[Encoding]string{
|
||||||
Identity: string(0x00) + "Decentralize everything!!!",
|
Identity: string(0x00) + "Decentralize everything!!!",
|
||||||
|
Base2: "00100010001100101011000110110010101101110011101000111001001100001011011000110100101111010011001010010000001100101011101100110010101110010011110010111010001101000011010010110111001100111001000010010000100100001",
|
||||||
Base16: "f446563656e7472616c697a652065766572797468696e67212121",
|
Base16: "f446563656e7472616c697a652065766572797468696e67212121",
|
||||||
Base16Upper: "F446563656E7472616C697A652065766572797468696E67212121",
|
Base16Upper: "F446563656E7472616C697A652065766572797468696E67212121",
|
||||||
Base32: "birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijbee",
|
Base32: "birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijbee",
|
||||||
@@ -117,6 +118,7 @@ func BenchmarkRoundTrip(b *testing.B) {
|
|||||||
|
|
||||||
bases := map[string]Encoding{
|
bases := map[string]Encoding{
|
||||||
"Identity": Identity,
|
"Identity": Identity,
|
||||||
|
"Base2": Base2,
|
||||||
"Base16": Base16,
|
"Base16": Base16,
|
||||||
"Base16Upper": Base16Upper,
|
"Base16Upper": Base16Upper,
|
||||||
"Base32": Base32,
|
"Base32": Base32,
|
||||||
|
|||||||
Reference in New Issue
Block a user