brianhempel / base_x

Convert numbers into and out of any base in Ruby; avoid ambiguous characters like 1, l, and I!
Other
13 stars 2 forks source link

Which base62 implementations is this compatible with? #1

Open coolaj86 opened 2 years ago

coolaj86 commented 2 years ago

Which base62 implementations is this compatible with?

Reference Strings

For reference, I believe this is what base62 encoding and decoding should look like:

Raw   : "Hello, 世界"
Base64: SGVsbG8sIOS4lueVjA (18 chars)
Base62: 1wJfrzvdbuFbL65vcS (18 chars)

Raw   : "Hello World"
Base64: SGVsbG8gV29ybGQ (15 chars)
Base62: 73XpUgyMwkGr29M (15 chars)

Raw   : [0] (1 bytes)
Base64: AA (2 chars)
Base62: 00 (2 chars)

Raw   : [ 0, 0, 0, 0, 255, 255, 255, 255 ]
Base64: AAAAAP____8 (11 chars)
Base62: 000004gfFC3 (11 chars)

Raw   : [ 255, 255, 255, 255, 0, 0, 0, 0 ]
Base64: _____wAAAAA (11 chars)
Base62: LygHZwPV2MC (11 chars)

Reference Implementation

I generated that using https://github.com/keybase/saltpack/encoding/basex, which seems to be correct and agree with other implementations, such as https://github.com/oconnor663/basex_gmp.

package main

import (
    "encoding/base64"
    "fmt"

    "github.com/keybase/saltpack/encoding/basex"
)

func main() {
    for _, src := range [][]byte{
        []byte("Hello, 世界"),
        []byte("Hello World"),
        {0},
        {0, 0, 0, 0, 255, 255, 255, 255},
        {255, 255, 255, 255, 0, 0, 0, 0},
    } {
        // Uses the GMP character set "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
        b62 := basex.Base62StdEncoding.EncodeToString(src)
        b64 := base64.RawURLEncoding.EncodeToString(src)

        if src[0] == 0x0 || src[1] == 255 {
            fmt.Printf("Raw   : %v (%d bytes)\n", src, len(src))
        } else {
            fmt.Printf("Raw   : %v (%d bytes)\n", string(src), len(src))
        }
        fmt.Printf("Base64: %s (%d chars)\n", b64, len(b64))
        fmt.Printf("Base62: %s (%d chars)\n", b62, len(b62))
        fmt.Println("")
    }
}
coolaj86 commented 2 years ago

Looks like all of these must be "BaseX" implementations of Base62. It seems to match the others:

1wJfrzvdbuFbL65vcS
73XpUgyMwkGr29M
00
00000000000000000
000000000000000000000000000000000
000004gfFC3
LygHZwPV2MC

I learned a little ruby real quick to figure that out.

require 'bundler/setup'
require 'base_x'

puts BaseX::Base62DUL.encode("Hello, 世界")
puts BaseX::Base62DUL.encode("Hello World")
puts BaseX::Base62DUL.encode("\x00")
puts BaseX::Base62DUL.encode("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
puts BaseX::Base62DUL.encode("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
puts BaseX::Base62DUL.encode("\x00\x00\x00\x00\xff\xff\xff\xff")
puts BaseX::Base62DUL.encode("\xff\xff\xff\xff\x00\x00\x00\x00")
echo <<EOF >> Gemfile
source 'https://rubygems.org'

gem 'base_x'
EOF

bundle install --path vendor/bundle

bundle exec ruby main.rb