diff --git a/encoder.go b/encoder.go new file mode 100644 index 0000000..490026f --- /dev/null +++ b/encoder.go @@ -0,0 +1,29 @@ +package ID + +import "encoding/base64" + +func Decode(input string) (t Type, lastError error) { + ret, err := base64.URLEncoding.DecodeString(input) + + if err != nil { + lastError = err + return + } + + for i := 2; i >= 0; i-- { + t <<= 8 + t |= Type(ret[i]) + } + + return +} + +func (t Type) Encode() string { + var buffer [3]byte + for i := 0; i < 3; i++ { + buffer[i] = byte(t) + t >>= 8 + } + + return base64.URLEncoding.EncodeToString(buffer[:]) +} diff --git a/encoder_test.go b/encoder_test.go new file mode 100644 index 0000000..2365279 --- /dev/null +++ b/encoder_test.go @@ -0,0 +1,38 @@ +package ID_test + +import ( + "testing" + + "go.dedaa.de/julixau/inftut/ID" +) + +// Verify that the Encoder works +func TestEncode(t *testing.T) { + totest := ID.Type(100) + str := totest.Encode() + + if str != "ZAAA" { + t.Fail() + } + + // encode a number that only fits in 3 bytes + totest = ID.Type(100000) + if totest.Encode() != "oIYB" { + t.Fail() + } +} + +// Test the decoder against the Encoder +func TestDecode(t *testing.T) { + id := ID.Type(100000) + totest := id.Encode() + + t.Log(id, totest) + if res, err := ID.Decode(totest); err != nil { + t.Fatal(err) + } else if res != id { + t.Fatal(res) + } else { + t.Log(res) + } +} diff --git a/generator.go b/generator.go new file mode 100644 index 0000000..287889c --- /dev/null +++ b/generator.go @@ -0,0 +1,25 @@ +package ID + +import "math/rand" + +const MaxID = 2 << 24 + +type Type uint + +type Generator struct { + // IDEA: i hate you + step Type + Last Type +} + +func (idg Generator) Next() Type { + idg.Last = (idg.Last + idg.step) % MaxID + return idg.Last +} + +func New(seed uint32) Generator { + return Generator{ + Last: Type(seed % MaxID), + step: Type((rand.Uint32() % MaxID) | 1), + } +}