Skip to content

Commit

Permalink
utils: remove google/uuid package
Browse files Browse the repository at this point in the history
  • Loading branch information
changkun committed Mar 27, 2021
1 parent 0f538e4 commit 8a69c98
Show file tree
Hide file tree
Showing 25 changed files with 189 additions and 972 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module changkun.de/x/redir
go 1.16

require (
github.com/google/uuid v1.2.0
go.mongodb.org/mongo-driver v1.4.6
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
)
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
Expand Down
8 changes: 6 additions & 2 deletions internal/db/visit.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"fmt"

"changkun.de/x/redir/internal/models"
"github.com/google/uuid"
"changkun.de/x/redir/internal/utils"
)

// RecordVisit records a visit event. If the visit is a new user, it returns
Expand All @@ -19,7 +19,11 @@ func (db *Store) RecordVisit(ctx context.Context, v *models.Visit) (string, erro

// if visitor ID does not present, then generate a new visitor ID.
if v.VisitorID == "" {
v.VisitorID = uuid.NewString()
id, err := utils.NewUUID()
if err != nil {
panic(err) // impossible unless system error.
}
v.VisitorID = id.String()
}

_, err := col.InsertOne(ctx, v)
Expand Down
159 changes: 159 additions & 0 deletions internal/utils/uuid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package utils

import (
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"math"
"math/big"
"sort"
"strings"
)

// random function
var rander = rand.Reader

var nilUUID uuid // empty UUID, all zeros

// A uuid is a 128 bit (16 byte) Universal Unique IDentifier
// as defined in RFC 4122.
type uuid [16]byte

// String returns the string form of uuid
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
// or "" if uuid is invalid.
func (u uuid) String() string {
var buf [36]byte
encodeHex(buf[:], u)
return string(buf[:])
}

// NewUUID creates a new uuid.
func NewUUID() (uuid, error) {
var u uuid
_, err := io.ReadFull(rander, u[:])
if err != nil {
return nilUUID, err
}
u[6] = (u[6] & 0x0f) | 0x40 // Version 4
u[8] = (u[8] & 0x3f) | 0x80 // Variant is 10
return u, nil
}

func encodeHex(dst []byte, u uuid) {
hex.Encode(dst, u[:4])
dst[8] = '-'
hex.Encode(dst[9:13], u[4:6])
dst[13] = '-'
hex.Encode(dst[14:18], u[6:8])
dst[18] = '-'
hex.Encode(dst[19:23], u[8:10])
dst[23] = '-'
hex.Encode(dst[24:], u[10:])
}

// NewUUIDShort creates a new uuid and encodes it to a short form.
func NewUUIDShort() (string, error) {
id, err := NewUUID()
if err != nil {
return "", err
}
return uuidEncoder.Encode(id), nil
}

// a is the default alphabet used.
const a = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

type alphabet struct {
chars [57]string
len int64
}

func (a *alphabet) Length() int64 {
return a.len
}

// Index returns the index of the first instance of t in the alphabet,
// or an error if t is not present.
func (a *alphabet) Index(t string) (int64, error) {
for i, char := range a.chars {
if char == t {
return int64(i), nil
}
}
return 0, fmt.Errorf("element '%v' is not part of the alphabet", t)
}

// newAlphabet removes duplicates and sort it to ensure reproducability.
func newAlphabet(s string) alphabet {
abc := dedupe(strings.Split(s, ""))

if len(abc) != 57 {
panic("encoding alphabet is not 57-bytes long")
}

sort.Strings(abc)
a := alphabet{
len: int64(len(abc)),
}
copy(a.chars[:], abc)
return a
}

// dudupe removes duplicate characters from s.
func dedupe(s []string) []string {
var out []string
m := make(map[string]bool)

for _, char := range s {
if _, ok := m[char]; !ok {
m[char] = true
out = append(out, char)
}
}

return out
}

var uuidEncoder = &base57{newAlphabet(a)}

type base57 struct {
// alphabet is the character set to construct the UUID from.
alphabet alphabet
}

// Encode encodes uuid.UUID into a string using the least significant
// bits (LSB) first according to the alphabet. if the most significant
// bits (MSB) are 0, the string might be shorter.
func (b base57) Encode(u uuid) string {
var num big.Int
num.SetString(strings.Replace(u.String(), "-", "", 4), 16)

// Calculate encoded length.
factor := math.Log(float64(25)) / math.Log(float64(b.alphabet.Length()))
length := math.Ceil(factor * float64(len(u)))

return b.numToString(&num, int(length))
}

// numToString converts a number a string using the given alpabet.
func (b *base57) numToString(number *big.Int, padToLen int) string {
var (
out string
digit *big.Int
)

for number.Uint64() > 0 {
number, digit = new(big.Int).DivMod(number,
big.NewInt(b.alphabet.Length()), new(big.Int))
out += b.alphabet.chars[digit.Int64()]
}

if padToLen > 0 {
remainder := math.Max(float64(padToLen-len(out)), 0)
out = out + strings.Repeat(b.alphabet.chars[0], int(remainder))
}

return out
}
24 changes: 24 additions & 0 deletions internal/utils/uuid_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package utils_test

import (
"testing"

"changkun.de/x/redir/internal/utils"
)

func TestNewUUID(t *testing.T) {
id, err := utils.NewUUID()
if err != nil {
t.Fatal("cannot allocate a new uuid")
}

t.Log(id)
}
func TestNewUUIDShort(t *testing.T) {
id, err := utils.NewUUIDShort()
if err != nil {
t.Fatal("cannot allocate a new uuid")
}

t.Log(id)
}
9 changes: 0 additions & 9 deletions vendor/github.com/google/uuid/.travis.yml

This file was deleted.

10 changes: 0 additions & 10 deletions vendor/github.com/google/uuid/CONTRIBUTING.md

This file was deleted.

9 changes: 0 additions & 9 deletions vendor/github.com/google/uuid/CONTRIBUTORS

This file was deleted.

27 changes: 0 additions & 27 deletions vendor/github.com/google/uuid/LICENSE

This file was deleted.

19 changes: 0 additions & 19 deletions vendor/github.com/google/uuid/README.md

This file was deleted.

80 changes: 0 additions & 80 deletions vendor/github.com/google/uuid/dce.go

This file was deleted.

12 changes: 0 additions & 12 deletions vendor/github.com/google/uuid/doc.go

This file was deleted.

1 change: 0 additions & 1 deletion vendor/github.com/google/uuid/go.mod

This file was deleted.

Loading

0 comments on commit 8a69c98

Please sign in to comment.