pax_global_header00006660000000000000000000000064136642144110014514gustar00rootroot0000000000000052 comment=cd0e5141f51dfcadb8311fd8e495eb11126a8010 base58-1.2.0/000077500000000000000000000000001366421441100126035ustar00rootroot00000000000000base58-1.2.0/.gitignore000066400000000000000000000000071366421441100145700ustar00rootroot00000000000000.idea/ base58-1.2.0/LICENSE000066400000000000000000000021571366421441100136150ustar00rootroot00000000000000MIT License Copyright (c) 2017 Denis Subbotin Copyright (c) 2017 Nika Jones Copyright (c) 2017 Philip Schlump 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. base58-1.2.0/README.md000066400000000000000000000026611366421441100140670ustar00rootroot00000000000000# Fast Implementation of Base58 encoding [![GoDoc](https://godoc.org/github.com/mr-tron/base58?status.svg)](https://godoc.org/github.com/mr-tron/base58) [![Go Report Card](https://goreportcard.com/badge/github.com/mr-tron/base58)](https://goreportcard.com/report/github.com/mr-tron/base58) [![Used By](https://sourcegraph.com/github.com/mr-tron/base58/-/badge.svg)](https://sourcegraph.com/github.com/mr-tron/base58?badge) Fast implementation of base58 encoding in Go. Base algorithm is copied from https://github.com/trezor/trezor-crypto/blob/master/base58.c ## Benchmark Trivial - encoding via big.Int (over libraries use this implemenation) Fast - optimized algorythm from trezor ``` BenchmarkTrivialBase58Encoding-4 123063 9568 ns/op BenchmarkFastBase58Encoding-4 690040 1598 ns/op BenchmarkTrivialBase58Decoding-4 275216 4301 ns/op BenchmarkFastBase58Decoding-4 1812105 658 ns/op ``` Encoding - **faster by 6 times** Decoding - **faster by 6 times** ## Usage example ```go package main import ( "fmt" "github.com/mr-tron/base58" ) func main() { encoded := "1QCaxc8hutpdZ62iKZsn1TCG3nh7uPZojq" num, err := base58.Decode(encoded) if err != nil { fmt.Printf("Demo %v, got error %s\n", encoded, err) } chk := base58.Encode(num) if encoded == string(chk) { fmt.Printf ( "Successfully decoded then re-encoded %s\n", encoded ) } } ``` base58-1.2.0/alphabet.go000066400000000000000000000014661366421441100147210ustar00rootroot00000000000000package base58 // Alphabet is a a b58 alphabet. type Alphabet struct { decode [128]int8 encode [58]byte } // NewAlphabet creates a new alphabet from the passed string. // // It panics if the passed string is not 58 bytes long or isn't valid ASCII. func NewAlphabet(s string) *Alphabet { if len(s) != 58 { panic("base58 alphabets must be 58 bytes long") } ret := new(Alphabet) copy(ret.encode[:], s) for i := range ret.decode { ret.decode[i] = -1 } for i, b := range ret.encode { ret.decode[b] = int8(i) } return ret } // BTCAlphabet is the bitcoin base58 alphabet. var BTCAlphabet = NewAlphabet("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") // FlickrAlphabet is the flickr base58 alphabet. var FlickrAlphabet = NewAlphabet("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ") base58-1.2.0/base58.go000066400000000000000000000070561366421441100142310ustar00rootroot00000000000000package base58 import ( "fmt" ) // Encode encodes the passed bytes into a base58 encoded string. func Encode(bin []byte) string { return FastBase58EncodingAlphabet(bin, BTCAlphabet) } // EncodeAlphabet encodes the passed bytes into a base58 encoded string with the // passed alphabet. func EncodeAlphabet(bin []byte, alphabet *Alphabet) string { return FastBase58EncodingAlphabet(bin, alphabet) } // FastBase58Encoding encodes the passed bytes into a base58 encoded string. func FastBase58Encoding(bin []byte) string { return FastBase58EncodingAlphabet(bin, BTCAlphabet) } // FastBase58EncodingAlphabet encodes the passed bytes into a base58 encoded // string with the passed alphabet. func FastBase58EncodingAlphabet(bin []byte, alphabet *Alphabet) string { size := len(bin) zcount := 0 for zcount < size && bin[zcount] == 0 { zcount++ } // It is crucial to make this as short as possible, especially for // the usual case of bitcoin addrs size = zcount + // This is an integer simplification of // ceil(log(256)/log(58)) (size-zcount)*555/406 + 1 out := make([]byte, size) var i, high int var carry uint32 high = size - 1 for _, b := range bin { i = size - 1 for carry = uint32(b); i > high || carry != 0; i-- { carry = carry + 256*uint32(out[i]) out[i] = byte(carry % 58) carry /= 58 } high = i } // Determine the additional "zero-gap" in the buffer (aside from zcount) for i = zcount; i < size && out[i] == 0; i++ { } // Now encode the values with actual alphabet in-place val := out[i-zcount:] size = len(val) for i = 0; i < size; i++ { out[i] = alphabet.encode[val[i]] } return string(out[:size]) } // Decode decodes the base58 encoded bytes. func Decode(str string) ([]byte, error) { return FastBase58DecodingAlphabet(str, BTCAlphabet) } // DecodeAlphabet decodes the base58 encoded bytes using the given b58 alphabet. func DecodeAlphabet(str string, alphabet *Alphabet) ([]byte, error) { return FastBase58DecodingAlphabet(str, alphabet) } // FastBase58Decoding decodes the base58 encoded bytes. func FastBase58Decoding(str string) ([]byte, error) { return FastBase58DecodingAlphabet(str, BTCAlphabet) } // FastBase58DecodingAlphabet decodes the base58 encoded bytes using the given // b58 alphabet. func FastBase58DecodingAlphabet(str string, alphabet *Alphabet) ([]byte, error) { if len(str) == 0 { return nil, fmt.Errorf("zero length string") } zero := alphabet.encode[0] b58sz := len(str) var zcount int for i := 0; i < b58sz && str[i] == zero; i++ { zcount++ } var t, c uint64 // the 32bit algo stretches the result up to 2 times binu := make([]byte, 2*((b58sz*406/555)+1)) outi := make([]uint32, (b58sz+3)/4) for _, r := range str { if r > 127 { return nil, fmt.Errorf("high-bit set on invalid digit") } if alphabet.decode[r] == -1 { return nil, fmt.Errorf("invalid base58 digit (%q)", r) } c = uint64(alphabet.decode[r]) for j := len(outi) - 1; j >= 0; j-- { t = uint64(outi[j])*58 + c c = t >> 32 outi[j] = uint32(t & 0xffffffff) } } // initial mask depends on b58sz, on further loops it always starts at 24 bits mask := (uint(b58sz%4) * 8) if mask == 0 { mask = 32 } mask -= 8 outLen := 0 for j := 0; j < len(outi); j++ { for mask < 32 { // loop relies on uint overflow binu[outLen] = byte(outi[j] >> mask) mask -= 8 outLen++ } mask = 24 } // find the most significant byte post-decode, if any for msb := zcount; msb < len(binu); msb++ { if binu[msb] > 0 { return binu[msb-zcount : outLen], nil } } // it's all zeroes return binu[:outLen], nil } base58-1.2.0/base58/000077500000000000000000000000001366421441100136725ustar00rootroot00000000000000base58-1.2.0/base58/DEPRECATED.md000066400000000000000000000002401366421441100156100ustar00rootroot00000000000000Files from this directory was copied to level up directory ========================================================== Now all development will be on top levelbase58-1.2.0/base58/alphabet.go000066400000000000000000000014661366421441100160100ustar00rootroot00000000000000package base58 // Alphabet is a a b58 alphabet. type Alphabet struct { decode [128]int8 encode [58]byte } // NewAlphabet creates a new alphabet from the passed string. // // It panics if the passed string is not 58 bytes long or isn't valid ASCII. func NewAlphabet(s string) *Alphabet { if len(s) != 58 { panic("base58 alphabets must be 58 bytes long") } ret := new(Alphabet) copy(ret.encode[:], s) for i := range ret.decode { ret.decode[i] = -1 } for i, b := range ret.encode { ret.decode[b] = int8(i) } return ret } // BTCAlphabet is the bitcoin base58 alphabet. var BTCAlphabet = NewAlphabet("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") // FlickrAlphabet is the flickr base58 alphabet. var FlickrAlphabet = NewAlphabet("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ") base58-1.2.0/base58/base58.go000066400000000000000000000140451366421441100153140ustar00rootroot00000000000000package base58 import ( "fmt" "math/big" ) var ( bn0 = big.NewInt(0) bn58 = big.NewInt(58) ) // Encode encodes the passed bytes into a base58 encoded string. func Encode(bin []byte) string { return FastBase58Encoding(bin) } // EncodeAlphabet encodes the passed bytes into a base58 encoded string with the // passed alphabet. func EncodeAlphabet(bin []byte, alphabet *Alphabet) string { return FastBase58EncodingAlphabet(bin, alphabet) } // FastBase58Encoding encodes the passed bytes into a base58 encoded string. func FastBase58Encoding(bin []byte) string { return FastBase58EncodingAlphabet(bin, BTCAlphabet) } // FastBase58EncodingAlphabet encodes the passed bytes into a base58 encoded // string with the passed alphabet. func FastBase58EncodingAlphabet(bin []byte, alphabet *Alphabet) string { zero := alphabet.encode[0] binsz := len(bin) var i, j, zcount, high int var carry uint32 for zcount < binsz && bin[zcount] == 0 { zcount++ } size := ((binsz-zcount)*138/100 + 1) // allocate one big buffer up front buf := make([]byte, size*2+zcount) // use the second half for the temporary buffer tmp := buf[size+zcount:] high = size - 1 for i = zcount; i < binsz; i++ { j = size - 1 for carry = uint32(bin[i]); j > high || carry != 0; j-- { carry = carry + 256*uint32(tmp[j]) tmp[j] = byte(carry % 58) carry /= 58 } high = j } for j = 0; j < size && tmp[j] == 0; j++ { } // Use the first half for the result b58 := buf[:size-j+zcount] if zcount != 0 { for i = 0; i < zcount; i++ { b58[i] = zero } } for i = zcount; j < size; i++ { b58[i] = alphabet.encode[tmp[j]] j++ } return string(b58) } // TrivialBase58Encoding encodes the passed bytes into a base58 encoded string // (inefficiently). func TrivialBase58Encoding(a []byte) string { return TrivialBase58EncodingAlphabet(a, BTCAlphabet) } // TrivialBase58EncodingAlphabet encodes the passed bytes into a base58 encoded // string (inefficiently) with the passed alphabet. func TrivialBase58EncodingAlphabet(a []byte, alphabet *Alphabet) string { zero := alphabet.encode[0] idx := len(a)*138/100 + 1 buf := make([]byte, idx) bn := new(big.Int).SetBytes(a) var mo *big.Int for bn.Cmp(bn0) != 0 { bn, mo = bn.DivMod(bn, bn58, new(big.Int)) idx-- buf[idx] = alphabet.encode[mo.Int64()] } for i := range a { if a[i] != 0 { break } idx-- buf[idx] = zero } return string(buf[idx:]) } // Decode decodes the base58 encoded bytes. func Decode(str string) ([]byte, error) { return FastBase58Decoding(str) } // DecodeAlphabet decodes the base58 encoded bytes using the given b58 alphabet. func DecodeAlphabet(str string, alphabet *Alphabet) ([]byte, error) { return FastBase58DecodingAlphabet(str, alphabet) } // FastBase58Decoding decodes the base58 encoded bytes. func FastBase58Decoding(str string) ([]byte, error) { return FastBase58DecodingAlphabet(str, BTCAlphabet) } // FastBase58DecodingAlphabet decodes the base58 encoded bytes using the given // b58 alphabet. func FastBase58DecodingAlphabet(str string, alphabet *Alphabet) ([]byte, error) { if len(str) == 0 { return nil, fmt.Errorf("zero length string") } var ( t uint64 zmask, c uint32 zcount int b58u = []rune(str) b58sz = len(b58u) outisz = (b58sz + 3) / 4 // check to see if we need to change this buffer size to optimize binu = make([]byte, (b58sz+3)*3) bytesleft = b58sz % 4 zero = rune(alphabet.encode[0]) ) if bytesleft > 0 { zmask = (0xffffffff << uint32(bytesleft*8)) } else { bytesleft = 4 } var outi = make([]uint32, outisz) for i := 0; i < b58sz && b58u[i] == zero; i++ { zcount++ } for _, r := range b58u { if r > 127 { return nil, fmt.Errorf("High-bit set on invalid digit") } if alphabet.decode[r] == -1 { return nil, fmt.Errorf("Invalid base58 digit (%q)", r) } c = uint32(alphabet.decode[r]) for j := (outisz - 1); j >= 0; j-- { t = uint64(outi[j])*58 + uint64(c) c = uint32(t>>32) & 0x3f outi[j] = uint32(t & 0xffffffff) } if c > 0 { return nil, fmt.Errorf("Output number too big (carry to the next int32)") } if outi[0]&zmask != 0 { return nil, fmt.Errorf("Output number too big (last int32 filled too far)") } } // the nested for-loop below is the same as the original code: // switch (bytesleft) { // case 3: // *(binu++) = (outi[0] & 0xff0000) >> 16; // //-fallthrough // case 2: // *(binu++) = (outi[0] & 0xff00) >> 8; // //-fallthrough // case 1: // *(binu++) = (outi[0] & 0xff); // ++j; // //-fallthrough // default: // break; // } // // for (; j < outisz; ++j) // { // *(binu++) = (outi[j] >> 0x18) & 0xff; // *(binu++) = (outi[j] >> 0x10) & 0xff; // *(binu++) = (outi[j] >> 8) & 0xff; // *(binu++) = (outi[j] >> 0) & 0xff; // } var j, cnt int for j, cnt = 0, 0; j < outisz; j++ { for mask := byte(bytesleft-1) * 8; mask <= 0x18; mask, cnt = mask-8, cnt+1 { binu[cnt] = byte(outi[j] >> mask) } if j == 0 { bytesleft = 4 // because it could be less than 4 the first time through } } for n, v := range binu { if v > 0 { start := n - zcount if start < 0 { start = 0 } return binu[start:cnt], nil } } return binu[:cnt], nil } // TrivialBase58Decoding decodes the base58 encoded bytes (inefficiently). func TrivialBase58Decoding(str string) ([]byte, error) { return TrivialBase58DecodingAlphabet(str, BTCAlphabet) } // TrivialBase58DecodingAlphabet decodes the base58 encoded bytes // (inefficiently) using the given b58 alphabet. func TrivialBase58DecodingAlphabet(str string, alphabet *Alphabet) ([]byte, error) { zero := alphabet.encode[0] var zcount int for i := 0; i < len(str) && str[i] == zero; i++ { zcount++ } leading := make([]byte, zcount) var padChar rune = -1 src := []byte(str) j := 0 for ; j < len(src) && src[j] == byte(padChar); j++ { } n := new(big.Int) for i := range src[j:] { c := alphabet.decode[src[i]] if c == -1 { return nil, fmt.Errorf("illegal base58 data at input index: %d", i) } n.Mul(n, bn58) n.Add(n, big.NewInt(int64(c))) } return append(leading, n.Bytes()...), nil } base58-1.2.0/base58/base58_2_test.go000066400000000000000000000012131366421441100165650ustar00rootroot00000000000000package base58 import "testing" func TestBase58_test2(t *testing.T) { testAddr := []string{ "1QCaxc8hutpdZ62iKZsn1TCG3nh7uPZojq", "1DhRmSGnhPjUaVPAj48zgPV9e2oRhAQFUb", "17LN2oPYRYsXS9TdYdXCCDvF2FegshLDU2", "14h2bDLZSuvRFhUL45VjPHJcW667mmRAAn", } for ii, vv := range testAddr { // num := Base58Decode([]byte(vv)) // chk := Base58Encode(num) num, err := FastBase58Decoding(vv) if err != nil { t.Errorf("Test %d, expected success, got error %s\n", ii, err) } chk := FastBase58Encoding(num) if vv != string(chk) { t.Errorf("Test %d, expected=%s got=%s Address did base58 encode/decode correctly.", ii, vv, chk) } } } base58-1.2.0/base58/base58_test.go000066400000000000000000000047301366421441100163530ustar00rootroot00000000000000package base58 import ( "crypto/rand" "encoding/hex" "testing" ) type testValues struct { dec []byte enc string } var n = 5000000 var testPairs = make([]testValues, 0, n) func initTestPairs() { if len(testPairs) > 0 { return } // pre-make the test pairs, so it doesn't take up benchmark time... for i := 0; i < n; i++ { data := make([]byte, 32) rand.Read(data) testPairs = append(testPairs, testValues{dec: data, enc: FastBase58Encoding(data)}) } } func randAlphabet() *Alphabet { // Permutes [0, 127] and returns the first 58 elements. // Like (math/rand).Perm but using crypto/rand. var randomness [128]byte rand.Read(randomness[:]) var bts [128]byte for i, r := range randomness { j := int(r) % (i + 1) bts[i] = bts[j] bts[j] = byte(i) } return NewAlphabet(string(bts[:58])) } func TestFastEqTrivialEncodingAndDecoding(t *testing.T) { for k := 0; k < 10; k++ { testEncDecLoop(t, randAlphabet()) } testEncDecLoop(t, BTCAlphabet) testEncDecLoop(t, FlickrAlphabet) } func testEncDecLoop(t *testing.T, alph *Alphabet) { for j := 1; j < 256; j++ { var b = make([]byte, j) for i := 0; i < 100; i++ { rand.Read(b) fe := FastBase58EncodingAlphabet(b, alph) te := TrivialBase58EncodingAlphabet(b, alph) if fe != te { t.Errorf("encoding err: %#v", hex.EncodeToString(b)) } fd, ferr := FastBase58DecodingAlphabet(fe, alph) if ferr != nil { t.Errorf("fast error: %v", ferr) } td, terr := TrivialBase58DecodingAlphabet(te, alph) if terr != nil { t.Errorf("trivial error: %v", terr) } if hex.EncodeToString(b) != hex.EncodeToString(td) { t.Errorf("decoding err: %s != %s", hex.EncodeToString(b), hex.EncodeToString(td)) } if hex.EncodeToString(b) != hex.EncodeToString(fd) { t.Errorf("decoding err: %s != %s", hex.EncodeToString(b), hex.EncodeToString(fd)) } } } } func BenchmarkTrivialBase58Encoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { TrivialBase58Encoding([]byte(testPairs[i].dec)) } } func BenchmarkFastBase58Encoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { FastBase58Encoding(testPairs[i].dec) } } func BenchmarkTrivialBase58Decoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { TrivialBase58Decoding(testPairs[i].enc) } } func BenchmarkFastBase58Decoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { FastBase58Decoding(testPairs[i].enc) } } base58-1.2.0/base58_2_test.go000066400000000000000000000012131366421441100154760ustar00rootroot00000000000000package base58 import "testing" func TestBase58_test2(t *testing.T) { testAddr := []string{ "1QCaxc8hutpdZ62iKZsn1TCG3nh7uPZojq", "1DhRmSGnhPjUaVPAj48zgPV9e2oRhAQFUb", "17LN2oPYRYsXS9TdYdXCCDvF2FegshLDU2", "14h2bDLZSuvRFhUL45VjPHJcW667mmRAAn", } for ii, vv := range testAddr { // num := Base58Decode([]byte(vv)) // chk := Base58Encode(num) num, err := FastBase58Decoding(vv) if err != nil { t.Errorf("Test %d, expected success, got error %s\n", ii, err) } chk := FastBase58Encoding(num) if vv != string(chk) { t.Errorf("Test %d, expected=%s got=%s Address did base58 encode/decode correctly.", ii, vv, chk) } } } base58-1.2.0/base58_test.go000066400000000000000000000047261366421441100152710ustar00rootroot00000000000000package base58 import ( "encoding/hex" "math/rand" "testing" ) type testValues struct { dec []byte enc string } var n = 5000000 var testPairs = make([]testValues, 0, n) func initTestPairs() { if len(testPairs) > 0 { return } // pre-make the test pairs, so it doesn't take up benchmark time... for i := 0; i < n; i++ { data := make([]byte, 32) rand.Read(data) testPairs = append(testPairs, testValues{dec: data, enc: FastBase58Encoding(data)}) } } func randAlphabet() *Alphabet { // Permutes [0, 127] and returns the first 58 elements. // Like (math/rand).Perm but using crypto/rand. var randomness [128]byte rand.Read(randomness[:]) var bts [128]byte for i, r := range randomness { j := int(r) % (i + 1) bts[i] = bts[j] bts[j] = byte(i) } return NewAlphabet(string(bts[:58])) } func TestFastEqTrivialEncodingAndDecoding(t *testing.T) { for k := 0; k < 10; k++ { testEncDecLoop(t, randAlphabet()) } testEncDecLoop(t, BTCAlphabet) testEncDecLoop(t, FlickrAlphabet) } func testEncDecLoop(t *testing.T, alph *Alphabet) { for j := 1; j < 256; j++ { var b = make([]byte, j) for i := 0; i < 100; i++ { rand.Read(b) fe := FastBase58EncodingAlphabet(b, alph) te := TrivialBase58EncodingAlphabet(b, alph) if fe != te { t.Errorf("encoding err: %#v", hex.EncodeToString(b)) } fd, ferr := FastBase58DecodingAlphabet(fe, alph) if ferr != nil { t.Errorf("fast error: %v", ferr) } td, terr := TrivialBase58DecodingAlphabet(te, alph) if terr != nil { t.Errorf("trivial error: %v", terr) } if hex.EncodeToString(b) != hex.EncodeToString(td) { t.Errorf("decoding err: %s != %s", hex.EncodeToString(b), hex.EncodeToString(td)) } if hex.EncodeToString(b) != hex.EncodeToString(fd) { t.Errorf("decoding err: %s != %s", hex.EncodeToString(b), hex.EncodeToString(fd)) } } } } func BenchmarkTrivialBase58Encoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { TrivialBase58Encoding([]byte(testPairs[i].dec)) } } func BenchmarkFastBase58Encoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { FastBase58Encoding(testPairs[i].dec) } } func BenchmarkTrivialBase58Decoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { TrivialBase58Decoding(testPairs[i].enc) } } func BenchmarkFastBase58Decoding(b *testing.B) { initTestPairs() b.ResetTimer() for i := 0; i < b.N; i++ { FastBase58Decoding(testPairs[i].enc) } } base58-1.2.0/doc.go000066400000000000000000000007051366421441100137010ustar00rootroot00000000000000/* Package base58 provides fast implementation of base58 encoding. Base58 Usage To decode a base58 string: encoded := "1QCaxc8hutpdZ62iKZsn1TCG3nh7uPZojq" buf, _ := base58.Decode(encoded) To encode the same data: encoded := base58.Encode(buf) With custom alphabet customAlphabet := base58.NewAlphabet("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") encoded := base58.EncodeAlphabet(buf, customAlphabet) */ package base58 base58-1.2.0/examples/000077500000000000000000000000001366421441100144215ustar00rootroot00000000000000base58-1.2.0/examples/cli/000077500000000000000000000000001366421441100151705ustar00rootroot00000000000000base58-1.2.0/examples/cli/cli.go000066400000000000000000000014041366421441100162650ustar00rootroot00000000000000package main import ( "fmt" "os" "github.com/mr-tron/base58" ) func main() { exampleBase58Encoded := []string{ "1QCaxc8hutpdZ62iKZsn1TCG3nh7uPZojq", "1DhRmSGnhPjUaVPAj48zgPV9e2oRhAQFUb", "17LN2oPYRYsXS9TdYdXCCDvF2FegshLDU2", "14h2bDLZSuvRFhUL45VjPHJcW667mmRAAn", } // If a base58 string is on the command line, then use that instead of the 4 exampels above. if len(os.Args) > 1 { exampleBase58Encoded = os.Args[1:] } for _, vv := range exampleBase58Encoded { num, err := base58.Decode(vv) if err != nil { fmt.Printf("Demo %s, got error %s\n", vv, err) continue } chk := base58.Encode(num) if vv == string(chk) { fmt.Printf("Successfully decoded then re-encoded %s\n", vv) } else { fmt.Printf("Failed on %s\n", vv) } } } base58-1.2.0/examples/wif/000077500000000000000000000000001366421441100152065ustar00rootroot00000000000000base58-1.2.0/examples/wif/main.go000066400000000000000000000044351366421441100164670ustar00rootroot00000000000000package main import ( "bytes" "crypto/sha256" "encoding/hex" "flag" "fmt" "io" "io/ioutil" "os" "github.com/mr-tron/base58" ) func checkSum(b []byte) []byte { sh1, sh2 := sha256.New(), sha256.New() sh1.Write(b) sh2.Write(sh1.Sum(nil)) return sh2.Sum(nil) } func main() { var ( err error bin []byte help = flag.Bool("h", false, "display this message") lnBreak = flag.Int("b", 76, "break encoded string into num character lines. Use 0 to disable line wrapping") input = flag.String("i", "-", `input file (use: "-" for stdin)`) output = flag.String("o", "-", `output file (use: "-" for stdout)`) decode = flag.Bool("d", false, `decode input`) check = flag.Bool("k", false, `use sha256 check`) useError = flag.Bool("e", false, `write error to stderr`) ) flag.Parse() if *help { flag.Usage() os.Exit(0) } fin, fout := os.Stdin, os.Stdout if *input != "-" { if fin, err = os.Open(*input); err != nil { fmt.Fprintln(os.Stderr, "input file err:", err) os.Exit(1) } } if *output != "-" { if fout, err = os.Create(*output); err != nil { fmt.Fprintln(os.Stderr, "output file err:", err) os.Exit(1) } } if bin, err = ioutil.ReadAll(fin); err != nil { fmt.Fprintln(os.Stderr, "read input err:", err) os.Exit(1) } if *decode { decoded, err := base58.Decode(string(bin)) if err != nil { fmt.Fprintln(os.Stderr, "decode input err:", err) os.Exit(1) } var checkResult bool if *check { chk := len(decoded) - 4 decodedCk := decoded[chk:] decoded = decoded[:chk] sum := checkSum(decoded) checkResult = hex.EncodeToString(sum[:4]) == hex.EncodeToString(decodedCk) } _, err = io.Copy(fout, bytes.NewReader(decoded)) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } if *check && !checkResult { if *useError { fmt.Fprintf(os.Stderr, "%t\n", false) } os.Exit(3) } os.Exit(0) } if *check { sum := checkSum(bin) bin = append(bin, sum[:4]...) } encoded := base58.Encode(bin) if *lnBreak > 0 { lines := (len(encoded) / *lnBreak) + 1 for i := 0; i < lines; i++ { start := i * *lnBreak end := start + *lnBreak if i == lines-1 { fmt.Fprintln(fout, encoded[start:]) return } fmt.Fprintln(fout, encoded[start:end]) } } fmt.Fprintln(fout, encoded) } base58-1.2.0/go.mod000066400000000000000000000000521366421441100137060ustar00rootroot00000000000000module github.com/mr-tron/base58 go 1.12 base58-1.2.0/trivial.go000066400000000000000000000033601366421441100146060ustar00rootroot00000000000000package base58 import ( "fmt" "math/big" ) var ( bn0 = big.NewInt(0) bn58 = big.NewInt(58) ) // TrivialBase58Encoding encodes the passed bytes into a base58 encoded string // (inefficiently). func TrivialBase58Encoding(a []byte) string { return TrivialBase58EncodingAlphabet(a, BTCAlphabet) } // TrivialBase58EncodingAlphabet encodes the passed bytes into a base58 encoded // string (inefficiently) with the passed alphabet. func TrivialBase58EncodingAlphabet(a []byte, alphabet *Alphabet) string { zero := alphabet.encode[0] idx := len(a)*138/100 + 1 buf := make([]byte, idx) bn := new(big.Int).SetBytes(a) var mo *big.Int for bn.Cmp(bn0) != 0 { bn, mo = bn.DivMod(bn, bn58, new(big.Int)) idx-- buf[idx] = alphabet.encode[mo.Int64()] } for i := range a { if a[i] != 0 { break } idx-- buf[idx] = zero } return string(buf[idx:]) } // TrivialBase58Decoding decodes the base58 encoded bytes (inefficiently). func TrivialBase58Decoding(str string) ([]byte, error) { return TrivialBase58DecodingAlphabet(str, BTCAlphabet) } // TrivialBase58DecodingAlphabet decodes the base58 encoded bytes // (inefficiently) using the given b58 alphabet. func TrivialBase58DecodingAlphabet(str string, alphabet *Alphabet) ([]byte, error) { zero := alphabet.encode[0] var zcount int for i := 0; i < len(str) && str[i] == zero; i++ { zcount++ } leading := make([]byte, zcount) var padChar rune = -1 src := []byte(str) j := 0 for ; j < len(src) && src[j] == byte(padChar); j++ { } n := new(big.Int) for i := range src[j:] { c := alphabet.decode[src[i]] if c == -1 { return nil, fmt.Errorf("illegal base58 data at input index: %d", i) } n.Mul(n, bn58) n.Add(n, big.NewInt(int64(c))) } return append(leading, n.Bytes()...), nil }