summaryrefslogtreecommitdiff
path: root/src/uuid.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/uuid.go')
-rw-r--r--src/uuid.go102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/uuid.go b/src/uuid.go
new file mode 100644
index 0000000..8b953f8
--- /dev/null
+++ b/src/uuid.go
@@ -0,0 +1,102 @@
+package uuid
+
+import (
+ "crypto/rand"
+ "encoding/hex"
+ "errors"
+ "io"
+ "strings"
+)
+
+
+
+const (
+ ByteCount = 16
+ dashCount = 4
+ encodedLength = (ByteCount * 2) + dashCount
+)
+
+var (
+ dashIndexes = []int{ 8, 13, 18, 23 }
+ randomReader = rand.Reader
+
+ ErrBadLength = errors.New(
+ "uuid: str isn't of the correct length",
+ )
+ ErrBadDashCount = errors.New("uuid: Bad count of dashes in string")
+ ErrBadDashPosition = errors.New("uuid: Bad char in string")
+)
+
+
+
+type UUID [ByteCount]byte
+
+
+
+func NewFrom(r io.Reader) (UUID, error) {
+ var uuid UUID
+ _, err := io.ReadFull(r, uuid[:])
+ if err != nil {
+ return UUID{}, err
+ }
+ uuid[6] = (uuid[6] & 0x0f) | 0x40 // v4
+ uuid[8] = (uuid[8] & 0x3f) | 0x80 // variant 10
+ return uuid, nil
+}
+
+func New() UUID {
+ uuid, err := NewFrom(randomReader)
+ if err != nil {
+ panic(err)
+ }
+ return uuid
+}
+
+func (uuid UUID) String() string {
+ dst := [encodedLength]byte {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ '-',
+ 0, 0, 0, 0,
+ '-',
+ 0, 0, 0, 0,
+ '-',
+ 0, 0, 0, 0,
+ '-',
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ }
+
+ hex.Encode(dst[ 0:8], uuid[0:4])
+ hex.Encode(dst[ 9:13], uuid[4:6])
+ hex.Encode(dst[14:18], uuid[6:8])
+ hex.Encode(dst[19:23], uuid[8:10])
+ hex.Encode(dst[24:36], uuid[10:])
+
+ return string(dst[:])
+}
+
+func FromString(str string) (UUID, error) {
+ if len(str) != encodedLength {
+ return UUID{}, ErrBadLength
+ }
+
+ if strings.Count(str, "-") != dashCount {
+ return UUID{}, ErrBadDashCount
+ }
+
+ for _, idx := range dashIndexes {
+ if str[idx] != '-' {
+ return UUID{}, ErrBadDashPosition
+ }
+ }
+
+ hexstr := strings.Join(strings.Split(str, "-"), "")
+ data, err := hex.DecodeString(hexstr)
+ if err != nil {
+ return UUID{}, err
+ }
+
+ return [ByteCount]byte(data), nil
+}