{"id":13747390,"url":"https://github.com/rafaelsales/ulid","last_synced_at":"2025-05-14T04:07:32.810Z","repository":{"id":41159025,"uuid":"64732709","full_name":"rafaelsales/ulid","owner":"rafaelsales","description":"Universally Unique Lexicographically Sortable Identifier implementation for Ruby","archived":false,"fork":false,"pushed_at":"2025-01-26T20:34:22.000Z","size":70,"stargazers_count":492,"open_issues_count":4,"forks_count":30,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-11T14:20:22.989Z","etag":null,"topics":["id","primary-key","ruby","ulid","uuid"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/rafaelsales.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","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,"zenodo":null},"funding":{"github":["rafaelsales"]}},"created_at":"2016-08-02T07:00:45.000Z","updated_at":"2025-02-07T11:47:45.000Z","dependencies_parsed_at":"2024-01-13T03:01:07.674Z","dependency_job_id":"89023fa6-df24-42c2-9a60-f3a448c56acd","html_url":"https://github.com/rafaelsales/ulid","commit_stats":{"total_commits":64,"total_committers":18,"mean_commits":"3.5555555555555554","dds":0.40625,"last_synced_commit":"0f9fbaf2238b3be3ceb9efa4c2630d6ffebc64dc"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rafaelsales%2Fulid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rafaelsales%2Fulid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rafaelsales%2Fulid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rafaelsales%2Fulid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rafaelsales","download_url":"https://codeload.github.com/rafaelsales/ulid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254069214,"owners_count":22009509,"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":["id","primary-key","ruby","ulid","uuid"],"created_at":"2024-08-03T06:01:27.268Z","updated_at":"2025-05-14T04:07:32.766Z","avatar_url":"https://github.com/rafaelsales.png","language":"Ruby","readme":"# 🚨 Please hold on\n\n**If you're starting a new project with a empty database, use UUID v7 instead.**\n\n**If you’re trying to address database slowness caused by non-time-ordered UUIDs, such as UUIDv4, use UUIDv7 instead.**\n\n➡️ Read more at:\n- https://uuid7.com\n- https://buildkite.com/resources/blog/goodbye-integers-hello-uuids/\n\n---\n\n![Ruby](https://github.com/rafaelsales/ulid/workflows/Ruby/badge.svg)\n[![Gem Downloads](http://img.shields.io/gem/dt/ulid.svg)](https://rubygems.org/gems/ulid)\n[![GitHub License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/rafaelsales/ulid)\n\n# ulid\nUniversally Unique Lexicographically Sortable Identifier implementation for Ruby\n\nOfficial specification page: https://github.com/ulid/spec\n\n\u003ch1 align=\"center\"\u003e\n\t\u003cbr\u003e\n\t\u003cbr\u003e\n\t\u003cimg width=\"360\" src=\"logo.png\" alt=\"ulid\"\u003e\n\t\u003cbr\u003e\n\t\u003cbr\u003e\n\t\u003cbr\u003e\n\u003c/h1\u003e\n\n# Universally Unique Lexicographically Sortable Identifier\n\nUUID can be suboptimal for many uses-cases because:\n\n- It isn't the most character efficient way of encoding 128 bits of randomness\n- The string format itself is apparently based on the original MAC \u0026 time version (UUIDv1 from Wikipedia)\n- It provides no other information than randomness\n\nInstead, herein is proposed ULID:\n\n- 128-bit compatibility with UUID\n- 1.21e+24 unique ULIDs per millisecond\n- Lexicographically sortable!\n- Canonically encoded as a 26 character string, as opposed to the 36 character UUID\n- Uses Crockford's base32 for better efficiency and readability (5 bits per character)\n- Case insensitive\n- No special characters (URL safe)\n\n### Installation\n\n```\ngem install ulid\n```\n\n### Usage\n\n```ruby\nrequire 'ulid'\n\nULID.generate # 01ARZ3NDEKTSV4RRFFQ69G5FAV\n```\n\n**I want to generate a ULID using an arbitrary timestamp**\n\nYou can optionally pass a `Time` instance to `ULID.generate` to set an arbitrary timestamp component, i.e. the prefix of the ULID.\n\n```ruby\ntime_t1 = Time.now\nulid = ULID.generate(time_t1)\n```\n\n**I want to generate a ULID using an arbitrary suffix, i.e. without the randomness component**\n\nYou can optionally pass a 80-bit hex-encodable `String` on the argument `suffix` to `ULID.generate`. This will replace the randomness component\nby the suffix provided. This allows for fully deterministic ULIDs.\n\n```ruby\nrequire 'securerandom'\n\ntime = Time.now\nan_event_identifier = SecureRandom.uuid\nulid1 = ULID.generate(time, suffix: an_event_identifier)\nulid2 = ULID.generate(time, suffix: an_event_identifier)\nulid1 == ulid2 # true\n```\n\n## Specification\n\nBelow is the current specification of ULID as implemented in this repository. *Note: the binary format has not been implemented.*\n\n```\n 01AN4Z07BY      79KA1307SR9X4MV3\n\n|----------|    |----------------|\n Timestamp          Randomness\n  10 chars           16 chars\n   48bits             80bits\n   base32             base32\n```\n\n### Components\n\n**Timestamp**\n- 48 bit integer\n- UNIX-time in milliseconds\n- Won't run out of space till the year 10895 AD.\n\n**Randomness**\n- 80 bits\n- Cryptographically secure source of randomness, if possible\n\n### Sorting\n\nThe left-most character must be sorted first, and the right-most character sorted last. The default ASCII order is used for sorting.\n\n### Binary Layout and Byte Order\n\nThe components are encoded as 16 octets. Each component is encoded with the Most Significant Byte first (network byte order).\n\n```\n0                   1                   2                   3\n 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                      32_bit_uint_time_high                    |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|     16_bit_uint_time_low      |       16_bit_uint_random      |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                       32_bit_uint_random                      |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n|                       32_bit_uint_random                      |\n+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n```\n\n### String Representation\n\n```\nttttttttttrrrrrrrrrrrrrrrr\n\nwhere\nt is Timestamp\nr is Randomness\n```\n\n## Test Suite\n\n```\nbundle exec rake test\n```\n\n### Credits and references:\n\n* https://github.com/ulid/javascript\n","funding_links":["https://github.com/sponsors/rafaelsales"],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frafaelsales%2Fulid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frafaelsales%2Fulid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frafaelsales%2Fulid/lists"}