Commits

Miki Tebeka committed b3433bc Merge

Merge decode

Comments (0)

Files changed (5)

+0d4d732da7a828f6f39cc16d686f72c6786e41e0 v0.2.0
+2014-01-10 version 0.2.2
-# base62 - base62 encoding for Go
+# base62 - base62 encoding/decoding for Go
 
 
 ## About
 
 ## License
 
-    Copyright (C) 2011,2012,2013 Miki Tebeka <miki.tebeka@gmail.com>
+    Copyright (C) 2011-2014 Miki Tebeka <miki.tebeka@gmail.com>
 
     Permission is hereby granted, free of charge, to any person obtaining a copy
     of this software and associated documentation files (the "Software"), to
-/* base62 encoding
+/* base62 encoding/decoding
 
 base62 is usually used to encode short URLs.
 */
 package base62
 
-const (
-	alphabet = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-	Version = "0.1.0"
+import (
+	"math"
+	"strings"
 )
 
-// Encode encoders num to base62 string.
+const (
+	Alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	Version  = "0.2.0"
+)
+
+var base = uint64(len(Alphabet))
+
+// Encode encodes num to base62 string.
 func Encode(num uint64) string {
 	if num == 0 {
 		return "0"
 	}
 
 	arr := []uint8{}
-	base := uint64(len(alphabet))
 
 	for num > 0 {
 		rem := num % base
 		num = num / base
-		arr = append(arr, alphabet[rem])
+		arr = append(arr, Alphabet[rem])
 	}
 
 	// Reverse the result array
 
 	return string(arr)
 }
+
+// Decode decodes base62 string to a number.
+func Decode(b62 string) uint64 {
+	size := len(b62)
+	num := uint64(0)
+	base := float64(len(Alphabet))
+
+	for i, ch := range b62 {
+		idx := i + 1
+		loc := uint64(strings.IndexRune(Alphabet, ch))
+		pow := uint64(math.Pow(base, float64(size-idx)))
+		num += loc * pow
+	}
+
+	return num
+}
 )
 
 var testCases = []struct {
-	in uint64
-	out string
+	n   uint64
+	b62 string
 }{
 	{0, "0"},
-	{1, "b"},
-	{22, "w"},
-	{4444, "bjG"},
-	{7777777, "6Dwb"},
+	{10, "a"},
+	{630, "aa"},
+	{1097900471, "1ciG47"},
 }
 
 func TestEncode(t *testing.T) {
 	for _, tc := range testCases {
-		t.Logf("Testing %d\n", tc.in)
-		if v := Encode(tc.in); v != tc.out {
-			t.Fatalf("%d decoded to %s (should be %s)", tc.in, v, tc.out)
+		t.Logf("Testing %d\n", tc.n)
+		if v := Encode(tc.n); v != tc.b62 {
+			t.Fatalf("%d encoded to %s (should be %s)", tc.n, v, tc.b62)
 		}
 	}
 }
+
+func TestDecode(t *testing.T) {
+	for _, tc := range testCases {
+		t.Logf("Testing %s\n", tc.b62)
+		if n := Decode(tc.b62); n != tc.n {
+			t.Fatalf("%s decoded to %d (should be %d)", tc.b62, n, tc.n)
+		}
+	}
+}