1

For my restful api I want to implement shorter urls based on url-safe base42-encoded UUID's version 4 (In future I'll use MongoDB's internal one's instead).

The generation works fine, but the base64 library of Go doesn't seem to encode the UUID as string as expected. The outpout is 48 characters long instead of 22 (as shown here in Python).

Here is my code:

package main

import (
    "encoding/base64"
    "fmt"

    "github.com/nu7hatch/gouuid"
)

func printRandomUUID() {
    uid, _ := uuid.NewV4()
    uid64 := base64.URLEncoding.EncodeToString([]byte(uid.String()))
    fmt.Println(uid64, len(uid64))
}

func main() {
    for i := 0; i < 5; i++ {
        printRandomUUID()
    }
}

And here is a possible output:

OGJhNzdhODItNjc5Yi00OWIyLTYwOGEtODZkYjA2Mzk0MDJj 48
YzE3YTNmY2EtOWM1MC00ZjE2LTQ3YTAtZGI3ZGQyNGI4N2Fj 48
ODFmZDU3ZDgtNjA2Ni00ZjYwLTUyMDUtOTU0MDVhYzNjZTNh 48
NjhkNTY3ZDAtOGE1Yy00ZGY2LTVmZmMtZTg2ZDEwOTlmZjU3 48
MzhhZmU0MDctMDE3Ny00YjhjLTYyYzctYWYwMWNlMDkwOWRh 48


As shown is the output not shorter but longer! Did I implemented the encoding the wrong way?

Community
  • 1
  • 1
user3147268
  • 1,814
  • 7
  • 26
  • 39

1 Answers1

4

You are encoding an encoding

uid.String() 

Produces a hex string, you are then encoding those characters with base64.

you want to encode the bytes instead:

uid64 := base64.URLEncoding.EncodeToString(uid[:])

the uid[:] turns the [16]byte in to a slice, which is what EncodeToString requires.

On my machine, this produces:

EaHttz1oSvJnCVQOaPWLAQ== 24
JEqjA6xfQD9-Ebp4Lai0DQ== 24
UWvn3zWYRPdPXcE9bbDX9w== 24
mBMNZB4FSmlRl6t4bDOiHA== 24
O1JTaQHBRm1RP5FLB7pbwQ== 24
David Budworth
  • 11,248
  • 1
  • 36
  • 45
  • Thank you very much. And if I strip the equal signs at the end I will get my 22 character url. This saves my day after trying the hole time ;) – user3147268 Mar 31 '15 at 19:56