Last active
August 15, 2021 19:28
-
-
Save havlan/4936bc09dfeb08b2aaecbc9cb50da1c9 to your computer and use it in GitHub Desktop.
A key part of shortening URLs is creating a reasonable mapping from an ID (could be database entity) to a short string that redirects to a correct new url.
This file contains 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 ( | |
"errors" | |
"fmt" | |
"strings" | |
) | |
const ( | |
Alphabet string = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ" | |
Base int = len(Alphabet) | |
) | |
/* | |
Accepts string and decodes it into an ID for lookup | |
*/ | |
func Decode(url string) (base62Number int, err error) { | |
if url == "" { | |
return -1, errors.New("empty string not allowed") | |
} | |
var sum = 0 | |
for _, c := range url { | |
if strings.Contains(Alphabet, string(c)) { | |
sum = sum*Base + strings.Index(Alphabet, string(c)) | |
} else { | |
return -1, fmt.Errorf("unable to find character %c in Alphabet", c) | |
} | |
} | |
return sum, nil | |
} | |
/* | |
Accepts an integer key and encodes it into a string using alphabet | |
*/ | |
func Encode(key int) (url string, err error) { | |
if key == 0 { | |
return string(Alphabet[0]), nil | |
} | |
var output = "" | |
// as long as we have more data, collect | |
for key > 0 { | |
output = string(Alphabet[key%Base]) + output | |
key /= Base | |
} | |
return output, nil | |
} | |
func main() { | |
/* | |
Overall idea, user A with original url B inserts into DB and we get an ID | |
Use ID and Encode to get a string and return short version of url | |
User B with a GET request for something/short_url | |
System looks up short_url, gets ID | |
System retrieves original URL from DB | |
return original URL | |
*/ | |
for i := 0; i < 1000; i++ { | |
var encoded, _ = Encode(i) | |
fmt.Println(encoded) | |
var decoded, _ = Decode(encoded) | |
if i != decoded { | |
fmt.Printf("string comparison failed, string %d is not a match for %d\n", i, decoded) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment