Skip to content

Instantly share code, notes, and snippets.

@dc0d
Created March 12, 2013 05:18
Show Gist options
  • Save dc0d/5140546 to your computer and use it in GitHub Desktop.
Save dc0d/5140546 to your computer and use it in GitHub Desktop.
encode and decode from different number base; for example 9876543210 in base 36 would be 4jc8lii. I've learnt this from python code at http://stackoverflow.com/questions/1119722/base-62-conversion-in-python
func sample_usage() {
digits := "0123456789abcdefghijklmnopqrstuvwxyz" // base 36
var num int64 = 9876543210
fmt.Printf("input number is %d\n", num)
e := encode(num, digits)
fmt.Printf("encoded as %v\n", e)
d := decode(e, digits)
fmt.Printf("decoded as %v\n", d)
}
func decode(enced string, digits string) (ed int64) {
en := []rune(enced)
alf := []rune(digits)
base := len(alf)
lenen := len(en)
var num int64
var ilf map[rune]int64 = make(map[rune]int64)
for k, v := range alf {
ilf[v] = int64(k)
}
for i, vn := range en {
power := lenen - (i + 1)
num += ilf[vn] * int64(math.Pow(float64(base), float64(power)))
}
ed = num
return
}
func encode(num int64, digits string) (ed string) {
ab := []rune(digits)
if num == 0 {
ed = string(ab[0])
return
}
var res []rune
base := int64(len(ab))
for num > 0 {
rem := num % base
num = num / base
res = append(res, ab[rem])
}
res = reverseRuneSlice(res)
ed = string(res)
return
}
func reverseRuneSlice(slc []rune) (ed []rune) {
l := len(slc)
ed = make([]rune, l)
copy(ed, slc)
for i := 0; i < l/2; i++ {
ed[i], ed[l-i-1] = ed[l-i-1], ed[i]
}
return
}
@jehiah
Copy link

jehiah commented Mar 16, 2013

Is this different than strconv.FormatInt(i int64, base int) string and strconv.ParseInt(s string, base int, bitSize int) (i int64, err error)? It seems similar and i know i almost wrote the same thing before finding the strconv functions.

@dc0d
Copy link
Author

dc0d commented Mar 16, 2013

@jehiah Thanks, one other friend pointed out to me too. Sure using the standard library brings more consistency. The only difference here is the standard library supports bases up to at most 36 [0-9a-z] but this code allows you use bigger bases like 62 [0-9a-zA-Z] or even any other possible set of characters; for example [0-9a-z] + [Japanese characters: あ,わ,...] "Go" for base 1000!

@dc0d
Copy link
Author

dc0d commented Jan 16, 2015

Another usage I've encountered recently is generating Natural Area Code which excludes vowels and avoids potential confusion between "0" (zero) and "O" (capital "o"), and "1" (one) and "I" (capital "i"). (http://en.wikipedia.org/wiki/Natural_Area_Code)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment