Base128を作りました (Golang)
Base128とは 英数字(a-z, A-Z, 0-9)とひらがな(あ-ん)の128文字を使ってバイト列をエンコードするものです. 実用性はともかく,文字数はBase64より少なくなるというメリットがあります. デメリットは,エンコード後のデータ量がものすごく増えることと,あらかじめエンコード後/デコード後のデータ量がわからない点です. https://github.com/dozen/encoding 使い方 import import "github.com/dozen/encoding/base128" encode e := base128.NewEncoding(base128.StdEncoding) e.EncodeToString([]byte("Hello, world!")) //=>kZtけふ8ぢg7どぺmふQお decode e := base128.NewEncoding(base128.StdEncoding) fmt.Printf("%s\n", e.Decode("kZtけふ8ぢg7どぺmふQお")) //=>Hello, world! 実装 Base64を参考にして作り始めたのですがとりあえず動くようにしようとあれこれしている間に全く別物になってしまいました. Base64の場合,64文字を用いるので6bitを表現できます.エンコード時には,元の8bitのバイト列を6bitに区切るために,4byteずつuintに格納してから6bitずつビットシフトしています。 val := uint(src[si+0])<<16 | uint(src[si+1])<<8 | uint(src[si+2]) dst[di+0] = enc.encode[val>>18&0x3F] dst[di+1] = enc.encode[val>>12&0x3F] dst[di+2] = enc.encode[val>>6&0x3F] dst[di+3] = enc.encode[val&0x3F] こんなかんじです.encoding/base64/base64.goの100行目ぐらいのところです. これを参考にして,元の8bitのバイト列を7byteずつ取り出し,7bitずつ区切ることにしました.7byte=56bitなのでuintには収まる範囲です. val := uint(src[si+0])<<48 | uint(src[si+1])<<40 | uint(src[si+2])<<32 | uint(src[si+3])<<24 | uint(src[si+4])<<16 | uint(src[si+5])<<8 | uint(src[si+6]) dst[di+0] = enc.encode[val>>49&0x7F] dst[di+1] = enc....