{"id":18784216,"url":"https://github.com/sdrapkin/guid","last_synced_at":"2025-12-20T23:30:20.957Z","repository":{"id":230738824,"uuid":"780048258","full_name":"sdrapkin/guid","owner":"sdrapkin","description":"Fast cryptographically safe Guid generator for Go","archived":false,"fork":false,"pushed_at":"2024-12-20T14:45:44.000Z","size":5,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-12-29T11:51:49.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sdrapkin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-31T14:56:45.000Z","updated_at":"2024-12-20T14:34:16.000Z","dependencies_parsed_at":"2024-12-29T11:51:33.127Z","dependency_job_id":"dd766cbe-82b7-4bdc-8f09-2b87c1b769f5","html_url":"https://github.com/sdrapkin/guid","commit_stats":null,"previous_names":["sdrapkin/guid"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdrapkin%2Fguid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdrapkin%2Fguid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdrapkin%2Fguid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdrapkin%2Fguid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sdrapkin","download_url":"https://codeload.github.com/sdrapkin/guid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239699583,"owners_count":19682575,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T20:42:24.889Z","updated_at":"2025-12-20T23:30:20.949Z","avatar_url":"https://github.com/sdrapkin.png","language":"Go","funding_links":[],"categories":["UUID"],"sub_categories":["Utility/Miscellaneous","实用程序/Miscellaneous"],"readme":"# guid [![name](https://goreportcard.com/badge/github.com/sdrapkin/guid)](https://goreportcard.com/report/github.com/sdrapkin/guid) [![codecov](https://codecov.io/github/sdrapkin/guid/branch/master/graph/badge.svg?token=ARQFUQD5VP)](https://codecov.io/github/sdrapkin/guid) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go#uuid) \n## Fast cryptographically secure Guid generator for Go.\u003cbr\u003eBy [Stan Drapkin](https://github.com/sdrapkin/).\n\n`Guid` is defined as `type Guid [16]byte` and filled with 128 cryptographically strong bits.\n\n[Go playground](https://go.dev/play/p/l_Yj74HUpgl)\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/sdrapkin/guid\"\n)\n\nfunc main() {\n\tfor range 4 {\n\t\tfmt.Printf(\"%x\\n\", guid.New())\n\t}\n\tfmt.Println()\n\tfor range 4 {\n\t\tg := guid.New()\n\t\tfmt.Println(\u0026g) // calls g.String()\n\t}\n}\n```\n\n```\n79c9779af20dcd21fbe60f3b336ed08c\nda2026d38edca4371a476efd41333d23\n88c3033b002b0e73321509ef26de607f\na84e961ff7f09f5210ea04585f152e73\n\nWF8MvK5CUOrI-enEuvS0jw\nAOp8Voi5knpu1mg3RjzmSg\ngxOQRIVR4B_uGHD6OP76XA\nZo_hpnDxkOsAWLk1tIS6DA\n```\n\n## Why `guid`? 🔥\n\n`guid` is a high-performance, cryptographically secure UUID/GUID (Globally Unique Identifier) generator for Go. It's built for speed without compromising on security, offering a significant performance advantage—up to **10x faster** than `github.com/google/uuid`.\n\nBeyond raw speed, `guid` offers:\n\n* **Cryptographically Strong**: Generates 128 cryptographically secure bits for robust, unique identifiers.\n* **Optimized for Databases**: Includes special `GuidPG` and `GuidSS` types that generate sequential Guids, dramatically improving `INSERT` performance and preventing index fragmentation in PostgreSQL and SQL Server databases.\n* **Seamless Interoperability**: Easily integrate with existing `google/uuid` codebases, and even boost `uuid`'s performance by up to **4x** using `guid.Reader`.\n* **FIPS 140 Compliant**: Ensures adherence to stringent security standards.\n* **Zero Allocations for Core Operations**: `guid.New()` generates new Guids with no memory allocations, making it incredibly efficient.\n\n## Guid is ~10x faster than `github.com/google/uuid` 🔥\n\n* `guid.New()` is  6~10 ns \n* `guid.NewString()` is 40~60 ns\n* `String()` on existing guid is ~40 ns\n* multi-goroutine calls do not increase per-call latency\n* if your library is faster - please let me know!\n\n## API Overview\n**All APIs are safe for concurrent use by multiple goroutines.**\n| Functions | Description |\n|---|---|\n| `guid.New()` `Guid`           | Generate a new Guid |\n| `guid.NewString()` `string`   | Generate a new Guid as a Base64Url string |\n| `guid.NewPG()` `GuidPG`       | Generate a new PostgreSQL sequential Guid |\n| `guid.NewSS()` `GuidSS`       | Generate a new SQL Server sequential Guid |\n| `guid.Parse(s string)` `(Guid, error)` | Parse a Base64Url string into a Guid |\n| `guid.ParseBytes(src []byte)` `(Guid, error)` | Parse Base64Url bytes to a Guid |\n| `guid.FromBytes(src []byte)` `(Guid, error)`  | Parse 16-byte slice to a Guid |\n| `guid.DecodeBase64URL(dst []byte, src []byte)` `(ok bool)` | Decode a Base64Url slice into a Guid slice |\n| `guid.Reader` 🔥 implements `io.Reader`    | Faster alternative to `crypto/rand` |\n| guid.Nil                    | The zero-value Guid |\n\n| `Guid` methods | Description |\n|---|---|\n| `.String()` `string` | Encodes the Guid into Base64Url 22-char string `fmt.Stringer` |\n| `.EncodeBase64URL(dst []byte)` `error` | Like `.String()` but encodes into len(22) byte slice |\n| .MarshalBinary() | Implements `encoding.BinaryMarshaler` |\n| .UnmarshalBinary() | Implements `encoding.BinaryUnmarshaler` |\n| .MarshalText() | Implements `encoding.TextMarshaler` |\n| .UnmarshalText() | Implements `encoding.TextUnmarshaler` |\n\n| `GuidPG`, `GuidSS` methods | Description |\n|---|---|\n| `.Timestamp()` `time.Time` | Extracts the UTC timestamp |\n\n## Sequential Guids 🔥\n`guid` includes two special types `GuidPG` and `GuidSS` optimized for use as database primary keys (PostgreSQL and SQL Server). Their time-ordered composition helps prevent index fragmentation and improves `INSERT` performance compared to fully random Guids. Note that sequential sorting is only across `time.Now()` timestamp precision.\n\n* **`guid.NewPG()`**: Generates a `GuidPG`, which is sortable in **PostgreSQL**.\n \t- It is structured as `[8-byte timestamp][8 random bytes]`.\n* **`guid.NewSS()`**: Generates a `GuidSS`, which is sortable in **SQL Server**.\n\t- It is structured as `[8 random bytes][8-byte SQL Server-ordered timestamp]`.\n* `.Timestamp()` on `GuidPG`/`GuidSS` returns Guid creation time as UTC `time.Time`.\n\nBoth `GuidPG` and `GuidSS` are nearly as fast as `guid.New()`. They can be used as a standard `Guid` and support the same interfaces.\n\n***\n\n### Sequential Guid Example:\n\n```go\nfmt.Printf(\"%s\\t       %s\\t\\t\\t\\t%s\\t       %s\\n\",\n\t\"gpg.String()\", \"hex(gpg)\", \"gss.String()\", \"hex(gss)\")\nfor range 10 {\n\tgpg := guid.NewPG()\n\tgss := guid.NewSS()\n\tfmt.Println(\u0026gpg, hex.EncodeToString(gpg.Guid[:]), \u0026gss, hex.EncodeToString(gss.Guid[:]))\n}\n\ngpg := guid.NewPG()\ngss := guid.NewSS()\nfmt.Println(gpg.Timestamp()) // time.Time\nfmt.Println(gss.Timestamp()) // time.Time\n```\n```\ngpg.String()           hex(gpg)                         gss.String()           hex(gss)\nGFEU88wgQvDlahOowSGTKA 185114f3cc2042f0e56a13a8c1219328 9SurLKL6ti2l0BhRFPPMKA f52bab2ca2fab62da5d0185114f3cc28\nGFEU88wopdChlFba89-4yg 185114f3cc28a5d0a19456daf3dfb8ca yTRE6Rr1gISl0BhRFPPMKA c93444e91af58084a5d0185114f3cc28\nGFEU88ww9fA01GntVDQ_4w 185114f3cc30f5f034d469ed54343fe3 8SaILyee6q718BhRFPPMMA f126882f279eeaaef5f0185114f3cc30\nGFEU88ww9fASNFzZQJpv7Q 185114f3cc30f5f012345cd9409a6fed xZ3KYLzqJ0f18BhRFPPMMA c59dca60bcea2747f5f0185114f3cc30\nGFEU88ww9fAHgWvjAmkQJw 185114f3cc30f5f007816be302691027 yEif2kTQBcD18BhRFPPMMA c8489fda44d005c0f5f0185114f3cc30\nGFEU88ww9fD4_Vm3PG5Vuw 185114f3cc30f5f0f8fd59b73c6e55bb SRKgSiCc-gL18BhRFPPMMA 4912a04a209cfa02f5f0185114f3cc30\nGFEU88ww9fDzO_One7T6BA 185114f3cc30f5f0f33bf3a77bb4fa04 rGr2czgQcmr18BhRFPPMMA ac6af6733810726af5f0185114f3cc30\nGFEU88w5PqQAifEi5tqoWQ 185114f3cc393ea40089f122e6daa859 5YYbiI3p7P4-pBhRFPPMOQ e5861b888de9ecfe3ea4185114f3cc39\nGFEU88w5PqSFkX4bmxSvMQ 185114f3cc393ea485917e1b9b14af31 PqUPeiyessU-pBhRFPPMOQ 3ea50f7a2c9eb2c53ea4185114f3cc39\nGFEU88w5PqTsYX0kcZzL6Q 185114f3cc393ea4ec617d24719ccbe9 yFIlRwKZJNo-pBhRFPPMOQ c8522547029924da3ea4185114f3cc39\n2025-07-11 03:32:47.3597457 +0000 UTC\n2025-07-11 03:32:47.3597457 +0000 UTC\n```\n\n## Interoperability with `google/uuid` 🔥\n* If you must keep using `google/uuid`, use `guid` to increase performance by **2~4x**:\n```go\n// do this before using google/uuid\nuuid.SetRand(guid.Reader)\n```\n* Quick conversions between `guid` and `google/uuid` if you need `uuid` behavior:\n```go\ng := guid.New()\ngpg := guid.NewPG()\ngss := guid.NewSS()\n\nvar u uuid.UUID\n\nu = uuid.UUID(g) // copy by value\nfmt.Println(u)\n\nu = uuid.UUID(gpg.Guid) // copy by value\nfmt.Println(u)\n\nu = uuid.UUID(gss.Guid) // copy by value\nfmt.Println(u)\n\nuptr := (*uuid.UUID)(unsafe.Pointer(\u0026g)) // zero-copy cast\ng[0], g[1] = 0xAB, 0xCD\nfmt.Println(uptr)\n```\n```go\n05166521-a124-9d0c-cb11-7f0cbf3a030c\n1852e32a-5aac-bb9c-bffc-b330606813af\n7e8badae-57f8-c88d-bb9c-1852e32a5aac\nabcd6521-a124-9d0c-cb11-7f0cbf3a030c\n```\n\n## FIPS Ready\n* **FIPS-140 ready** (https://go.dev/doc/security/fips140)\n\t* set `GODEBUG=fips140=on` environment variable\n\t* https://go.dev/blog/fips140\n\n## uuid Benchmarks with and without `guid.Reader`\n\n| Benchmark Name | Time per Op | Bytes per Op  | Allocs per Op  |\n|---|---|---|---|\n| Benchmark_uuid_New_x10-8                                   | 3031 ns/op  | 160 B/op      | 10 allocs/op   |\n| Benchmark_uuid_New_**guidRand**_x10-8 🔥                   | 862.0 ns/op | 160 B/op      | 10 allocs/op   |\n| Benchmark_uuid_New_RandPool_x10-8                          | 747.6 ns/op | 0 B/op        | 0 allocs/op    |\n| Benchmark_uuid_New_RandPool_**guidRand**_x10-8 🔥          | 516.8 ns/op | 0 B/op        | 0 allocs/op    |\n| Benchmark_uuid_New_Parallel_x10-8                          | 1230 ns/op  | 160 B/op      | 10 allocs/op   |\n| Benchmark_uuid_New_Parallel_**guidRand**_x10-8 🔥          | 510.0 ns/op | 160 B/op      | 10 allocs/op   |\n| Benchmark_uuid_New_Parallel_RandPool_x10-8                 | 1430 ns/op  | 0 B/op        | 0 allocs/op    |\n| Benchmark_uuid_New_Parallel_RandPool_**guidRand**_x10-8 🔥 | 1185 ns/op  | 0 B/op        | 0 allocs/op    |\n\n\n## Guid Benchmarks [[raw](BENCHMARKS.md)]\n```\ngo test -bench=.* -benchtime=4s\ngoos: windows\ngoarch: amd64\npkg: github.com/sdrapkin/guid\ncpu: Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz\n```\n| Benchmarks guid [10 calls] | Time/op | Bytes/op | Allocs/op |\n|---|---|---|---|\n| guid_New_x10-8                          |  203.4 ns/op  |   0 B/op |  0 allocs/op |\n| guid_NewString_x10-8                    |  582.4 ns/op  | 240 B/op | 10 allocs/op |\n| guid_String_x10-8                       |  388.9 ns/op  | 240 B/op | 10 allocs/op |\n| guid_New_Parallel_x10-8 🔥               |  62.45 ns/op  |   0 B/op |  0 allocs/op |\n| guid_NewString_Parallel_x10-8           |  374.2 ns/op  | 240 B/op | 10 allocs/op |\n\n## Sequential Guid Benchmarks\n| `guid.NewPG()` vs `uuid.NewV7()` [10 calls] | Time/op | |\n|---|---|---|\n| **guid.NewPG()_x10_Sequential** | **386.4 ns/op** |\n| uuid.NewV7()_x10_Sequential | 887.9 ns/op | 2.3x slower ⏳\n| **guid.NewPG()_x10_Parallel** | **144.3 ns/op** |\n| uuid.NewV7()_x10_Parallel | 2575 ns/op | 18x slower ⏳\n\n\n### Alternative library benchmarks:\n| Benchmarks nanoid v1.35 [10 calls] | Time/op | Bytes/op | Allocs/op |\n|---|---|---|---|\n| `guid.NewString()` x10 Sequential       | **609.9 ns/op**   | 240 B/op | 10 allocs/op |\n| `guid.NewString()` x10 Parallel (8 CPU) | **384.0 ns/op**   | 240 B/op | 10 allocs/op |\n| `nanoid.New()` x10 Sequential           | 2257 ns/op        | 240 B/op | 10 allocs/op |\n| `nanoid.New()` x10 Parallel (8 CPU)     | 1337 ns/op        | 240 B/op | 10 allocs/op |\n\n| Benchmarks uuid [10 calls] | Time/op | Bytes/op | Allocs/op |\n|---|---|---|---|\n| uuid_New_x10-8                          |  2216 ns/op   | 160 B/op | 10 allocs/op |\n| uuid_New_RandPool_x10-8                 |  528.2 ns/op  |   0 B/op |  0 allocs/op |\n| uuid_New_Parallel_x10-8                 |  1064 ns/op   | 160 B/op | 10 allocs/op |\n| uuid_New_RandPool_Parallel_x10-8        |  1301 ns/op   |   0 B/op |  0 allocs/op |\n\n| Benchmarks [20 guid encodings] | Time/op | Bytes/op | Allocs/op |\n|---|---|---|---|\n| g.String-8                |  1025 ns/op   | 480 B/op | 20 allocs/op |\n| base64.RawURLEncoding.EncodeToString-8  |  1867 ns/op   | 960 B/op | 40 allocs/op |\n| g.EncodeBase64URL-8                  |  392.0 ns/op  |   0 B/op |  0 allocs/op |\n| base64.RawURLEncoding.Encode-8          |  463.4 ns/op  |   0 B/op |  0 allocs/op |\n\n## Documentation\n [![Go Reference](https://pkg.go.dev/badge/github.com/sdrapkin/guid.svg)](https://pkg.go.dev/github.com/sdrapkin/guid)\n\nFull `go doc` style documentation: https://pkg.go.dev/github.com/sdrapkin/guid\n\n## Requirements\n- Go 1.24+\n\n## Installation\n### Using `go get`\n\nTo install the `guid` package, run the following command:\n\n```sh\ngo get -u github.com/sdrapkin/guid\n```\n\nTo use the `guid` package in your Go project, import it as follows:\n\n```go\nimport \"github.com/sdrapkin/guid\"\n```\n## JSON Support\n\n`Guid` supports JSON marshalling and unmarshalling for both value and pointer types:\n\n- Value fields serialize as 22-character Base64Url strings.\n- Pointer fields serialize as strings or `null` (for nil pointers).\n- Zero-value Guids (`guid.Nil`) are handled correctly.\n\n### Example: JSON Marshalling\n```go\ntype User struct {\n\tID        guid.Guid  `json:\"id\"`\n\tManagerID *guid.Guid `json:\"mid\"`\n}\n\nu, u2 := User{ID: guid.New()}, User{}\ndata, _ := json.Marshal(u)\nfmt.Println(string(data)) // {\"id\":\"tI0EMdDXpOcvvGLktob4Ug\",\"mid\":null}\n\n_ = json.Unmarshal(data, \u0026u2)\nfmt.Println(u2.ID == u.ID) // true\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdrapkin%2Fguid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsdrapkin%2Fguid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdrapkin%2Fguid/lists"}