From 623adc49fb94ad6815ed1db02dbd3a5a0a77efa7 Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Thu, 14 Aug 2025 08:50:58 +0530 Subject: [PATCH 1/9] testing uuid run --- uuid/uuid.go | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 uuid/uuid.go diff --git a/uuid/uuid.go b/uuid/uuid.go new file mode 100644 index 0000000..7e730a4 --- /dev/null +++ b/uuid/uuid.go @@ -0,0 +1,5 @@ +package uuid + +func Newuuid() string { + return "gautam" +} From 2ef7d4ebb2bb35c1b9d0b3c54e735a40ae3ff96b Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Thu, 14 Aug 2025 11:14:40 +0530 Subject: [PATCH 2/9] test uuid v1 --- uuid/uuid.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/uuid/uuid.go b/uuid/uuid.go index 7e730a4..0b09ac4 100644 --- a/uuid/uuid.go +++ b/uuid/uuid.go @@ -1,5 +1,6 @@ package uuid -func Newuuid() string { - return "gautam" +func Newuuid() int { + time := 1234 + return time } From fb798d528889cd5ae93afd4049a39a7cfbbc2d08 Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Mon, 18 Aug 2025 00:41:07 +0530 Subject: [PATCH 3/9] main unignore --- .gitignore | 3 +-- main.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 main.go diff --git a/.gitignore b/.gitignore index bb24711..7cd1091 100644 --- a/.gitignore +++ b/.gitignore @@ -18,5 +18,4 @@ # vendor/ # Go workspace file -go.work -main.go \ No newline at end of file +go.work \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..0cb3cb1 --- /dev/null +++ b/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "fmt" + "time" + + "github.com/good-binary/utility/random" +) + +func main() { + fmt.Println(random.RandomFullName()) + t := time.Now() + fmt.Println(t.Format("20060102150405")) +} From ef6a6691970c653fae0e3c8df8f7a54fe042b35c Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Mon, 18 Aug 2025 00:56:26 +0530 Subject: [PATCH 4/9] implemented --- main.go | 8 +++----- uuid/uuid.go | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index 0cb3cb1..e52c63d 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,11 @@ package main import ( "fmt" - "time" - "github.com/good-binary/utility/random" + "github.com/good-binary/utility/uuid" ) func main() { - fmt.Println(random.RandomFullName()) - t := time.Now() - fmt.Println(t.Format("20060102150405")) + x := uuid.Newuuid() + fmt.Println(x) } diff --git a/uuid/uuid.go b/uuid/uuid.go index 0b09ac4..9e89eed 100644 --- a/uuid/uuid.go +++ b/uuid/uuid.go @@ -1,6 +1,15 @@ package uuid -func Newuuid() int { - time := 1234 - return time +import ( + "time" + + "github.com/good-binary/utility/random" +) + +func Newuuid() string { + t := time.Now() + x := t.Format("20060102150405") + y := random.RandomString(8, "", "") + uuid := x + y + return uuid } From 78c501a89861c803c143e9efed24e369bc2f6fe1 Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Mon, 18 Aug 2025 01:04:10 +0530 Subject: [PATCH 5/9] removed main --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7cd1091..bb24711 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,5 @@ # vendor/ # Go workspace file -go.work \ No newline at end of file +go.work +main.go \ No newline at end of file From e9f6f6ba638ed53ea4e5f44df1eb7b2968f0fc42 Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Sun, 31 Aug 2025 15:05:15 +0530 Subject: [PATCH 6/9] UUID done --- main.go | 41 ++++++++++++++++- uuid/README.md | 49 ++++++++++++++++++++ uuid/uuid.go | 114 ++++++++++++++++++++++++++++++++++++++++++---- uuid/uuid_test.go | 69 ++++++++++++++++++++++++++++ 4 files changed, 262 insertions(+), 11 deletions(-) create mode 100644 uuid/README.md create mode 100644 uuid/uuid_test.go diff --git a/main.go b/main.go index e52c63d..4fcb27b 100644 --- a/main.go +++ b/main.go @@ -1,12 +1,49 @@ package main import ( + "encoding/json" "fmt" + "log" "github.com/good-binary/utility/uuid" ) func main() { - x := uuid.Newuuid() - fmt.Println(x) + // Generate a new UUID + u := uuid.NewUUID() + fmt.Println("Generated UUID:", u.String()) + + // Validate the UUID string + valid := uuid.Validate(u.String()) + fmt.Println("Is valid?", valid) + + // Parse from string + parsed, err := uuid.Parse(u.String()) + if err != nil { + log.Fatal("Parse error:", err) + } + fmt.Println("Parsed UUID:", parsed.String()) + + // Compare UUIDs + fmt.Println("Equal?", u.Equal(parsed)) + + // Nil UUID + nilUUID := uuid.Nil() + fmt.Println("Nil UUID:", nilUUID.String()) + + // Marshal to JSON + jsonBytes, err := json.Marshal(u) + if err != nil { + log.Fatal("Marshal error:", err) + } + fmt.Println("UUID as JSON:", string(jsonBytes)) + + // Unmarshal from JSON + var u2 uuid.UUID + err = json.Unmarshal(jsonBytes, &u2) + if err != nil { + log.Fatal("Unmarshal error:", err) + } + fmt.Println("Unmarshaled UUID:", u2.String()) + fmt.Println("Equal after unmarshal?", u.Equal(u2)) } diff --git a/uuid/README.md b/uuid/README.md new file mode 100644 index 0000000..72de379 --- /dev/null +++ b/uuid/README.md @@ -0,0 +1,49 @@ +# UUID Package + +This package provides utilities for UUID (Universally Unique Identifier) generation and manipulation using only Go's standard library. + +## Features +- Generate new UUIDs (v4) +- Parse UUID from string +- Convert UUID to string +- Validate a UUID string +- Compare two UUIDs +- Marshal/Unmarshal UUID to/from JSON +- Generate nil (zero value) UUID + +## Usage Example +```go +import "yourmodule/uuid" + +// Generate a new UUID (v4) +id := uuid.NewV4() + +// Convert to string +s := id.String() + +// Validate a UUID string +valid := uuid.Validate(s) + +// Parse from string +parsed, err := uuid.Parse(s) + +// Compare UUIDs +isEqual := id.Equal(parsed) + +// Nil UUID +zero := uuid.Nil() + +// Marshal/Unmarshal JSON +b, _ := json.Marshal(id) +var u2 uuid.UUID +_ = json.Unmarshal(b, &u2) +``` + +## Note +- UUID v1 (time-based) is **not** supported in the Go standard library. Calling `uuid.NewV1()` will return an error and a nil UUID. + +## Testing +Run unit tests: +```sh +go test ./uuid +``` diff --git a/uuid/uuid.go b/uuid/uuid.go index 9e89eed..70dcd8f 100644 --- a/uuid/uuid.go +++ b/uuid/uuid.go @@ -1,15 +1,111 @@ +// Package uuid provides utilities for UUID generation and manipulation using Go's standard library only. +// +// Features: +// - Generate new UUIDs (v4) +// - Parse UUID from string +// - Convert UUID to string +// - Validate a UUID string +// - Compare two UUIDs +// - Marshal/Unmarshal UUID to/from JSON +// - Generate nil (zero value) UUID +// +// Usage Example: +// +// import "yourmodule/uuid" +// id := uuid.NewV4() +// valid := uuid.Validate(id.String()) +// ... package uuid import ( - "time" - - "github.com/good-binary/utility/random" + "crypto/rand" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "strings" ) -func Newuuid() string { - t := time.Now() - x := t.Format("20060102150405") - y := random.RandomString(8, "", "") - uuid := x + y - return uuid +// UUID represents a 128-bit universally unique identifier (UUID). +type UUID [16]byte + +// NewV4 generates a new random (version 4) UUID. +func NewUUID() UUID { + var u UUID + _, err := rand.Read(u[:]) + if err != nil { + panic("uuid: cannot generate random UUID: " + err.Error()) + } + // Set version (4) and variant bits as per RFC 4122 + u[6] = (u[6] & 0x0f) | 0x40 // Version 4 + u[8] = (u[8] & 0x3f) | 0x80 // Variant is 10 + return u +} + +// Parse parses a UUID from string (accepts canonical form only). +func Parse(s string) (UUID, error) { + var u UUID + s = strings.ToLower(s) + if len(s) != 36 { + return Nil(), errors.New("uuid: invalid length") + } + // Remove dashes + hexStr := strings.ReplaceAll(s, "-", "") + if len(hexStr) != 32 { + return Nil(), errors.New("uuid: invalid format") + } + b, err := hex.DecodeString(hexStr) + if err != nil || len(b) != 16 { + return Nil(), errors.New("uuid: invalid hex") + } + copy(u[:], b) + return u, nil +} + +// String returns the canonical string representation of the UUID. +func (u UUID) String() string { + b := u[:] + return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", + b[0:4], b[4:6], b[6:8], b[8:10], b[10:16], + ) +} + +// Validate checks if a string is a valid UUID. +func Validate(s string) bool { + _, err := Parse(s) + return err == nil +} + +// Equal compares two UUIDs for equality. +func (u UUID) Equal(other UUID) bool { + return u == other +} + +// Nil returns a nil (zero value) UUID. +func Nil() UUID { + return UUID{} +} + +// MarshalJSON implements the json.Marshaler interface. +func (u UUID) MarshalJSON() ([]byte, error) { + return json.Marshal(u.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (u *UUID) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return err + } + parsed, err := Parse(s) + if err != nil { + return err + } + *u = parsed + return nil +} + +// Format implements fmt.Formatter for UUID. +func (u UUID) Format(f fmt.State, c rune) { + fmt.Fprintf(f, "%s", u.String()) } diff --git a/uuid/uuid_test.go b/uuid/uuid_test.go new file mode 100644 index 0000000..994fc83 --- /dev/null +++ b/uuid/uuid_test.go @@ -0,0 +1,69 @@ +package uuid + +import ( + "encoding/json" + "testing" +) + +func TestNewUUID(t *testing.T) { + u := NewUUID() + if u.String() == "" || !Validate(u.String()) { + t.Errorf("NewV4() generated invalid UUID: %s", u.String()) + } +} + +func TestParse(t *testing.T) { + u1 := NewUUID() + u2, err := Parse(u1.String()) + if err != nil { + t.Fatalf("Parse() error: %v", err) + } + if !u1.Equal(u2) { + t.Errorf("Parsed UUID does not match original") + } +} + +func TestValidate(t *testing.T) { + u := NewUUID().String() + if !Validate(u) { + t.Errorf("Validate() failed for valid UUID: %s", u) + } + if Validate("not-a-uuid") { + t.Errorf("Validate() passed for invalid UUID") + } +} + +func TestEqual(t *testing.T) { + u1 := NewUUID() + u2, _ := Parse(u1.String()) + if !u1.Equal(u2) { + t.Errorf("Equal() failed for identical UUIDs") + } + u3 := NewUUID() + if u1.Equal(u3) { + t.Errorf("Equal() passed for different UUIDs") + } +} + +func TestNil(t *testing.T) { + nilUUID := Nil() + if nilUUID.String() != "00000000-0000-0000-0000-000000000000" { + t.Errorf("Nil() did not return zero UUID") + } +} + +func TestMarshalUnmarshalJSON(t *testing.T) { + u := NewUUID() + data, err := json.Marshal(u) + if err != nil { + t.Fatalf("MarshalJSON() error: %v", err) + } + + var u2 UUID + if err := json.Unmarshal(data, &u2); err != nil { + t.Fatalf("UnmarshalJSON() error: %v", err) + } + if !u.Equal(u2) { + t.Errorf("UnmarshalJSON() did not produce equal UUID") + } +} From 91d27a696596325c16ad0aae6977697b7fc2e2b6 Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Sun, 31 Aug 2025 15:49:31 +0530 Subject: [PATCH 7/9] correction --- uuid/uuid_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uuid/uuid_test.go b/uuid/uuid_test.go index 994fc83..6e7a632 100644 --- a/uuid/uuid_test.go +++ b/uuid/uuid_test.go @@ -8,7 +8,7 @@ import ( func TestNewUUID(t *testing.T) { u := NewUUID() if u.String() == "" || !Validate(u.String()) { - t.Errorf("NewV4() generated invalid UUID: %s", u.String()) + t.Errorf("NewUUID generated invalid UUID: %s", u.String()) } } From 501ec80d7ecba6259dd98bda94208446a986286f Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Sun, 31 Aug 2025 20:54:25 +0530 Subject: [PATCH 8/9] removed main --- main.go | 49 ------------------------------------------------- uuid/README.md | 5 +---- 2 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 main.go diff --git a/main.go b/main.go deleted file mode 100644 index 4fcb27b..0000000 --- a/main.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "log" - - "github.com/good-binary/utility/uuid" -) - -func main() { - // Generate a new UUID - u := uuid.NewUUID() - fmt.Println("Generated UUID:", u.String()) - - // Validate the UUID string - valid := uuid.Validate(u.String()) - fmt.Println("Is valid?", valid) - - // Parse from string - parsed, err := uuid.Parse(u.String()) - if err != nil { - log.Fatal("Parse error:", err) - } - fmt.Println("Parsed UUID:", parsed.String()) - - // Compare UUIDs - fmt.Println("Equal?", u.Equal(parsed)) - - // Nil UUID - nilUUID := uuid.Nil() - fmt.Println("Nil UUID:", nilUUID.String()) - - // Marshal to JSON - jsonBytes, err := json.Marshal(u) - if err != nil { - log.Fatal("Marshal error:", err) - } - fmt.Println("UUID as JSON:", string(jsonBytes)) - - // Unmarshal from JSON - var u2 uuid.UUID - err = json.Unmarshal(jsonBytes, &u2) - if err != nil { - log.Fatal("Unmarshal error:", err) - } - fmt.Println("Unmarshaled UUID:", u2.String()) - fmt.Println("Equal after unmarshal?", u.Equal(u2)) -} diff --git a/uuid/README.md b/uuid/README.md index 72de379..3e30c3d 100644 --- a/uuid/README.md +++ b/uuid/README.md @@ -16,7 +16,7 @@ This package provides utilities for UUID (Universally Unique Identifier) generat import "yourmodule/uuid" // Generate a new UUID (v4) -id := uuid.NewV4() +id := uuid.NewUUID() // Convert to string s := id.String() @@ -39,9 +39,6 @@ var u2 uuid.UUID _ = json.Unmarshal(b, &u2) ``` -## Note -- UUID v1 (time-based) is **not** supported in the Go standard library. Calling `uuid.NewV1()` will return an error and a nil UUID. - ## Testing Run unit tests: ```sh From 07323d2264fadbbf45857bcef3c97fa2639aa065 Mon Sep 17 00:00:00 2001 From: Gautam Kumar Date: Sun, 31 Aug 2025 21:11:47 +0530 Subject: [PATCH 9/9] Completed --- uuid/uuid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uuid/uuid.go b/uuid/uuid.go index 70dcd8f..dc47d94 100644 --- a/uuid/uuid.go +++ b/uuid/uuid.go @@ -12,7 +12,7 @@ // Usage Example: // // import "yourmodule/uuid" -// id := uuid.NewV4() +// id := uuid.NewUUID() // valid := uuid.Validate(id.String()) // ... package uuid @@ -29,7 +29,7 @@ import ( // UUID represents a 128-bit universally unique identifier (UUID). type UUID [16]byte -// NewV4 generates a new random (version 4) UUID. +// NewUUID generates a new random (version 4) UUID. func NewUUID() UUID { var u UUID _, err := rand.Read(u[:])