-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Does not agree with Saltpack / GMP #2
Comments
This implementation is not string-compatible with typical big-int based implementation. Saying Base62 encoding and decoding, it is correct, it encodes arbitrary bytes to string using 62 characters, then correctly decodes the string back to the original bytes. The correctness is tested by large amount of random bytes, see the test file https://github.com/jxskiss/base62/blob/master/base62_test.go. This implemention is much performant than typical big-int based implementation. Regarding the reversed order of bytes, it's an implementation detail, and is the main reason we can get the performance. The folling test code gives this:
package testbase62
import (
"bytes"
"crypto/rand"
"testing"
"github.com/jxskiss/base62"
"github.com/keybase/saltpack/encoding/basex"
)
var bytes1K []byte
var bytes4K []byte
var bytes1M []byte
func init() {
bytes1K = make([]byte, 1024)
bytes4K = make([]byte, 4096)
bytes1M = make([]byte, 1024*1024)
_, err1 := rand.Read(bytes1K)
_, err2 := rand.Read(bytes4K)
_, err3 := rand.Read(bytes1M)
if err1 != nil || err2 != nil || err3 != nil {
panic("rand.Read got error")
}
}
func TestCorrectness(t *testing.T) {
b1 := base62.Encode(bytes4K)
b2, err := base62.Decode(b1)
if err != nil {
panic("base62 error")
}
if !bytes.Equal(bytes4K, b2) {
panic("base62 not equal")
}
n3 := basex.Base62StdEncoding.EncodedLen(len(bytes4K))
b3 := make([]byte, n3)
basex.Base62StdEncoding.Encode(b3, bytes4K)
n4 := basex.Base62StdEncoding.DecodedLen(len(b3))
b4 := make([]byte, n4)
nDec, err := basex.Base62StdEncoding.Decode(b4, b3)
if err != nil {
panic("basex error")
}
b4 = b4[:nDec]
if !bytes.Equal(bytes4K, b4) {
panic("basex not equal")
}
}
func Benchmark_jxskiss_Base62_1K(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = base62.Encode(bytes1K)
}
}
func Benchmark_saltpack_Base62_1K(b *testing.B) {
for i := 0; i < b.N; i++ {
n := basex.Base62StdEncoding.EncodedLen(len(bytes1K))
buf := make([]byte, n)
basex.Base62StdEncoding.Encode(buf, bytes1K)
}
}
func Benchmark_jxskiss_Base62_4K(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = base62.Encode(bytes4K)
}
}
func Benchmark_saltpack_Base62_4K(b *testing.B) {
for i := 0; i < b.N; i++ {
n := basex.Base62StdEncoding.EncodedLen(len(bytes4K))
buf := make([]byte, n)
basex.Base62StdEncoding.Encode(buf, bytes4K)
}
}
func Benchmark_jxskiss_Base62_1M(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = base62.Encode(bytes1M)
}
}
func Benchmark_saltpack_Base62_1M(b *testing.B) {
for i := 0; i < b.N; i++ {
n := basex.Base62StdEncoding.EncodedLen(len(bytes1M))
buf := make([]byte, n)
basex.Base62StdEncoding.Encode(buf, bytes1M)
}
} |
Hope I will get some time later to add the implementation details to README. |
Reference Strings
For reference, I here's the output of this library (jxskiss) compared to saltpack, which seems to also be compatible with the GMP and GnuPG Base62 implementations, even when using the same alphabet:
As you can see, it's not just a matter of the output being reversed, but the character sequences are entirely different.
Test Output Reference
The text was updated successfully, but these errors were encountered: