{"id":15409057,"url":"https://github.com/phatboyg/newid","last_synced_at":"2025-04-04T11:15:27.040Z","repository":{"id":2250118,"uuid":"3205091","full_name":"phatboyg/NewId","owner":"phatboyg","description":"A sequential id generator that works across nodes with no collisions","archived":false,"fork":false,"pushed_at":"2023-01-27T18:42:16.000Z","size":3696,"stargazers_count":673,"open_issues_count":0,"forks_count":79,"subscribers_count":26,"default_branch":"develop","last_synced_at":"2025-03-28T10:09:21.028Z","etag":null,"topics":["c-sharp","flake8","identity","masstransit","newid","uuid"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phatboyg.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}},"created_at":"2012-01-18T01:36:31.000Z","updated_at":"2025-03-25T08:47:31.000Z","dependencies_parsed_at":"2023-02-15T12:00:52.926Z","dependency_job_id":null,"html_url":"https://github.com/phatboyg/NewId","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phatboyg%2FNewId","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phatboyg%2FNewId/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phatboyg%2FNewId/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phatboyg%2FNewId/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phatboyg","download_url":"https://codeload.github.com/phatboyg/NewId/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166169,"owners_count":20894654,"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":["c-sharp","flake8","identity","masstransit","newid","uuid"],"created_at":"2024-10-01T16:36:49.032Z","updated_at":"2025-04-04T11:15:27.021Z","avatar_url":"https://github.com/phatboyg.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"## What is it\r\nNewId can be used as an embedded unique ID generator that produces 128 bit (16 bytes) sequential IDs. It is inspired from snowflake and flake. Read on to learn more.\r\n\r\n### The Problem\r\n\r\nA number of applications use unique identifiers to identify a data record. A common way for apps that use a relational database (RDBMS) is to delegate the generation of these IDs to the database - by means of a Identity column (MS-SQL) or similar.\r\nThis approach is fine for a small app, but quickly becomes a bottleneck at web-scale. See this post from the blokes at twitter: https://blog.twitter.com/2010/announcing-snowflake \r\nAnother use case is apps that use messaging to communicate between themselves - as is the case with a Microservices based architecture. These apps may require sequential unique IDs for messages.\r\n\r\n### An attempt at solutions\r\nA trivial approach is to use GUIDs/UUIDs generated in applications. While that works, in most frameworks GUIDs are not sequential. This takes away the ability to sort records based on their unique ids.\r\n\r\n### The Solution\r\nThe Erlang library flake (https://github.com/boundary/flake) adopted an approach of generating 128-bit, k-ordered ids (read time-ordered lexically) using the machines MAC, timestamp and a per thread sequence number. These IDs are sequential and wouldn't collide in a cluster of nodes running applicaitons that use these as UUIDs.\r\n\r\n### Sample Code\r\n\r\n```csharp\r\nNewId id = NewId.Next(); //produces an id like {11790000-cf25-b808-dc58-08d367322210}\r\n\r\n// Supports operations similar to GUID\r\nNewId id = NewId.Next().ToString(\"D\").ToUpperInvariant();\r\n// Produces 11790000-CF25-B808-2365-08D36732603A\r\n\r\n// Start from an id\r\nNewId id = new NewId(\"11790000-cf25-b808-dc58-08d367322210\");\r\n\r\n// Start with a byte-array\r\nvar bytes = new byte[] { 16, 23, 54, 74, 21, 14, 75, 32, 44, 41, 31, 10, 11, 12, 86, 42 };\r\nNewId theId = new NewId(bytes);\r\n```\r\n### When NOT to use sequential IDs\r\n(Adapted from the flake readme)\r\nThe generated ids are predictable by design. They should not be used in scenarios where unpredictability is a desired feature. \r\nThese IDs should **NOT** be used for:\r\n- Generating passwords\r\n- Security tokens \r\n- Anything else you wouldn't want someone to be able to guess.\r\n\r\nNewId generated ids expose the identity of the machine which generated the id (by way of its MAC address) and the time at which it did so. This could be a problem for some security-sensitive applications.\r\n\r\n**Don't** do modulo 2 arithmetic on flake ids with the expectation of random distribution. ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphatboyg%2Fnewid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphatboyg%2Fnewid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphatboyg%2Fnewid/lists"}