Last active
December 11, 2015 10:18
-
-
Save kylelemons/4585718 to your computer and use it in GitHub Desktop.
This is the base32 used in http://dnscurve.org/in-implement.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/hex" | |
"fmt" | |
) | |
var i2b = []byte("0123456789bcdfghjklmnpqrstuvwxyz") | |
var b2i = func() []byte { | |
var ascii [256]byte | |
for i := range ascii { | |
ascii[i] = 255 | |
} | |
for i, b := range i2b { | |
ascii[b] = byte(i) | |
} | |
return ascii[:] | |
}() | |
func encode(in []byte) (out []byte) { | |
var wide, bits uint | |
for len(in) > 0 { | |
// Add the 8 bits of data from the next `in` byte above the existing bits | |
wide, in, bits = wide|uint(in[0])<<bits, in[1:], bits+8 | |
for bits > 5 { | |
// Remove the least significant 5 bits and add their character to out | |
wide, out, bits = wide>>5, append(out, i2b[int(wide&0x1F)]), bits-5 | |
} | |
} | |
// If it wasn't a precise multiple of 40 bits, add some padding based on the remaining bits | |
if bits > 0 { | |
out = append(out, i2b[int(wide)]) | |
out = append(out, "====="[bits:]...) | |
} | |
return out | |
} | |
func decode(in []byte) (out []byte, err error) { | |
var wide, bits uint | |
for len(in) > 0 && in[0] != '=' { | |
// Add the 5 bits of data corresponding to the next `in` character above existing bits | |
wide, in, bits = wide|uint(b2i[int(in[0])])<<bits, in[1:], bits+5 | |
if bits >= 8 { | |
// Remove the least significant 8 bits of data and add it to out | |
wide, out, bits = wide>>8, append(out, byte(wide)), bits-8 | |
} | |
} | |
// If there was padding, there will be bits left, but they should be zero | |
if wide != 0 { | |
return nil, fmt.Errorf("extra data at end of decode") | |
} | |
return out, nil | |
} | |
func main() { | |
in, _ := hex.DecodeString("d7c0df45001a5be5e81c95e519be5199055237cb9116882cadcefe48ab735173") | |
want := "r6jzx210usqbgnm3pdtm1z6btd14pvdtkn5j8qnpgqzknpggkuw0====" | |
fmt.Println(string(encode(in))) | |
fmt.Println(want) | |
fmt.Printf("%x\n", in) | |
out, err := decode(encode(in)) | |
fmt.Printf("%x %v\n", out, err) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment