{"id":22636109,"url":"https://github.com/47degrees/memeid","last_synced_at":"2025-04-12T23:38:11.667Z","repository":{"id":36972470,"uuid":"213341177","full_name":"47degrees/memeid","owner":"47degrees","description":"RFC-compliant Universally Unique Identifiers (UUID) for the JVM","archived":false,"fork":false,"pushed_at":"2025-04-09T05:12:43.000Z","size":3487,"stargazers_count":56,"open_issues_count":58,"forks_count":6,"subscribers_count":36,"default_branch":"main","last_synced_at":"2025-04-12T23:38:03.704Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Scala","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/47degrees.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-07T09:17:31.000Z","updated_at":"2025-04-08T09:36:43.000Z","dependencies_parsed_at":"2023-12-22T06:30:44.142Z","dependency_job_id":"97082f9f-4dca-4fdb-8913-596d698b18fc","html_url":"https://github.com/47degrees/memeid","commit_stats":{"total_commits":835,"total_committers":23,"mean_commits":36.30434782608695,"dds":0.5497005988023952,"last_synced_commit":"b5c017e2a7d79f536358500a88f839fa6a6ce5a5"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47degrees%2Fmemeid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47degrees%2Fmemeid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47degrees%2Fmemeid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/47degrees%2Fmemeid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/47degrees","download_url":"https://codeload.github.com/47degrees/memeid/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647255,"owners_count":21139081,"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-12-09T03:18:17.276Z","updated_at":"2025-04-12T23:38:11.639Z","avatar_url":"https://github.com/47degrees.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"\\![](design-assets/other-file-formats/readme-header.png)\n\n`memeid` is a JVM library for generating [RFC-compliant](https://www.ietf.org/rfc/rfc4122.txt) Universal Unique Identifiers (UUIDs).\n\n\u003e A universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems.\n\u003e\n\u003e When generated according to the standard methods, UUIDs are for practical purposes unique. Their uniqueness does not depend on a central registration authority or coordination between the parties generating them, unlike most other numbering schemes.\n-- [Wikipedia article on UUIDs](https://en.wikipedia.org/wiki/Universally_unique_identifier)\n\n---\n\n- [Rationale](#rationale)\n- [Install](#install)\n  - [Java](#java)\n    - [Using maven](#using-maven)\n    - [Using gradle](#using-gradle)\n  - [Scala](#scala)\n- [Usage](#usage)\n  - [Scala](#scala)\n    - [UUID construction](#uuid-construction)\n      - [Time-based (v1)](#time-based-v1)\n      - [Random (v4)](#random-v4)\n      - [Namespaced (v3, v5)](#namespaced-v3-v5)\n      - [Semi-sequential, random (SQUUID)](#semi-sequential-random-squuid)\n    - [Java interoperability](#java-interoperability)\n    - [Literal syntax](#literal-syntax)\n    - [Integrations](#integrations)\n      - [Doobie](#doobie)\n      - [Circe](#circe)\n      - [Http4s](#http4s)\n        - [Path parameters](#path-parameters)\n        - [Query parameters](#query-parameters)\n      - [Tapir](#tapir)\n      - [FUUID](#fuuid)\n      - [Cats \u0026 Cats-effect](#cats--cats-effect)\n        - [Typeclasses](#typeclasses)\n        - [Constructors](#constructors)\n      - [Scalacheck](#scalacheck)\n- [Benchmarking](#benchmarking)\n- [References](#references)\n\n## Rationale\n\nThe UUID type that ships with the JVM `java.util.UUID` has a number of problems, namely:\n\n - [A bug in the comparison function that will never be fixed](https://bugs.java.com/bugdatabase/view_bug.do?bug_id=7025832) \n - Only provides UUID generation for random (V4) and non-namespaced pseudo-V3 UUIDs\n\nThis library aims to solve the aforementioned issues and provide an RFC-compliant `UUID` type with coherent comparison, a rich API to get its different fields and constructors for the UUID variants.\n\n## Install\n\n### Java\n\n#### Using maven\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.47deg\u003c/groupId\u003e\n    \u003cartifactId\u003ememeid\u003c/artifactId\u003e\n    \u003cversion\u003e0.8.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Using gradle\n\n```groovy\ncompile group: 'com.47deg', name: 'memeid', version: '0.8.0'\n```\n\n### Scala\n\nAdd this to your `build.sbt` file:\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s\" % \"0.8.0\"\n```\n\n## Usage\n\n### Scala\n\n#### UUID construction\n\n##### Time-based (v1)\n\nThe time-based (V1) variant of UUIDs is the fastest to generate. It uses a monotonic clock and node information to generate UUIDs.\n\n```scala\nimport memeid4s.UUID\n\nUUID.V1.next\n```\n\n##### Random (v4)\n\nThe cryptographically random variant, equivalent to `java.util.UUID/randomUUID`.\n\n```scala\nUUID.V4.random\n```\n\n##### Namespaced (v3, v5)\n\nNamespaced UUIDs are generated from a UUID (namespace) and a hashed value (name), V3 uses MD5 and V5 uses SHA1 hash.\n\n```scala\nval namespace = UUID.V1.next\n```\n\nWe can now create UUIDs with the namespace and an arbitrary value as the name. It automatically works with Strings and UUIDs:\n\n```scala\nUUID.V3(namespace, \"my-secret-code\")\n```\n\nIf you want to hash a custom type, you must provide an implicit `memeid4s.digest.Digestible` instance.\n\n```scala\nimport memeid4s.digest.Digestible\n\ncase class User(firstName: String, lastName: String)\n\nimplicit val digestibleUser: Digestible[User] =\n  (u: User) =\u003e u.firstName.getBytes ++ u.lastName.getBytes\n```\n\nThe implicit instance is used to convert your type into a byte array for hashing:\n\n```scala\nUUID.V3(namespace, User(\"Federico\", \"García Lorca\"))\n```\n\n##### Semi-sequential, random (SQUUID)\n\nSQUUIDs are a non-standard variaton of V4 UUIDs that are semi-sequential. They incorporate a time-component in their 32 most significant bits to generate UUIDs that don't fragment DB indexes.\n\n```scala\nUUID.V4.squuid\n```\n\n#### Java interoperability\n\n`memeid` provides conversion method between `UUID` and `java.util.UUID` through:\n\n```scala\nval j = java.util.UUID.fromString(\"a5fa7934-501c-46eb-9ea7-16de3086e6d8\")\n\nval u = memeid.UUID.fromString(\"8b4d1529-5fd0-4a91-8f4f-ceee10d1c060\")\n```\n\n```scala\nUUID.fromUUID(j)\n// res5: UUID = a5fa7934-501c-46eb-9ea7-16de3086e6d8\n\nu.asJava\n// res6: java.util.UUID = 8b4d1529-5fd0-4a91-8f4f-ceee10d1c060\n```\n\n#### Literal syntax\n\n`memeid` provides literal syntax with compile-time verification for UUIDs with the `uuid` interpolator. To use it, add this to your `build.sbt`:\n\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-literal\" % \"0.8.0\"\n```\n\nWe can now create UUIDs with literal syntax by importing `memeid.literal._`\n\n```scala\nimport memeid4s.literal._\n\nuuid\"cb096727-6a82-4abd-bc79-fc92be8c5d88\"\n// res7: UUID = cb096727-6a82-4abd-bc79-fc92be8c5d88\n```\n\nInvalid UUID literals will fail at compile time:\n\n```scala\nuuid\"not-a-uuid\"\n// error: invalid UUID: not-a-uuid\n// uuid\"not-a-uuid\"\n// ^^^^^^^^^^^^^^^^\n```\n\n#### Integrations\n\n`memeid` provides several modules which integrate with popular third-party libraries. If you see something missing don't hesitate to open an issue or send a patch.\n\n##### Doobie\n\nThe [Doobie](https://github.com/tpolecat/doobie) integration allows you to use the `UUID` type mapped to your database's UUID type.\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-doobie\" % \"0.8.0\"\n```\n\nTo have the [UUID mappings](https://tpolecat.github.io/doobie/docs/12-Custom-Mappings.html) available in scope you can import `memeid.doobie.implicits`.\n\n\n```scala\nimport memeid4s.doobie.implicits._\n\ndef select(uuid: UUID): Query0[UUID] =\n  sql\"\"\"SELECT id from test where id = $uuid\"\"\".query[UUID]\n\ndef insert(uuid: UUID): Update0 =\n  sql\"\"\"insert into test (id) values ($uuid)\"\"\".update\n\nval example = uuid\"58d61328-1b08-1171-1ee7-1283ed639e77\"\n```\n\n```scala\n{\n  for {\n    _ \u003c- insert(example).run.transact(transactor)\n    u \u003c- select(example).unique.transact(transactor)\n  } yield u\n}.unsafeRunSync()\n// res10: UUID = 58d61328-1b08-1171-1ee7-1283ed639e77\n```\n\n##### Circe\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-circe\" % \"0.8.0\"\n```\n\nYou can import `memeid.circe.implicits` to have the `Encoder` and `Decoder` instances for `UUID` in scope.\n\n```scala\nimport io.circe.Json\n\nimport io.circe.Encoder\nimport io.circe.Decoder\n\nimport memeid4s.circe.implicits._\n\nval uuid = uuid\"58d61328-1b08-1171-1ee7-1283ed639e77\"\n\nval json = Json.fromString(uuid.toString)\n```\n\n```scala\nEncoder[UUID].apply(uuid)\n// res11: Json = JString(value = \"58d61328-1b08-1171-1ee7-1283ed639e77\")\nDecoder[UUID].decodeJson(json)\n// res12: Decoder.Result[UUID] = Right(\n//   value = 58d61328-1b08-1171-1ee7-1283ed639e77\n// )\n```\n\n##### Http4s\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-http4s\" % \"0.8.0\"\n```\n\n###### Path parameters\n\nUsing `UUID` companion object we can extract UUIDs from path parameters in URLs:\n\n```scala\nimport cats.effect._\n\nimport org.http4s._\nimport org.http4s.dsl.io._\n\nHttpRoutes.of[IO] { case GET -\u003e Root / \"user\" / UUID(uuid) =\u003e\n  Ok(s\"Hello, $uuid!\")\n}\n```\n\n###### Query parameters\n\nThe http4s integrations provides implicit instances for `QueryParamDecoder[UUID]` and `QueryParamEncoder[UUID]`, which you can use to derive matchers for query parameters or send UUID in request query parameters.\n\n```scala\nimport cats.effect._\n\nimport org.http4s._\nimport org.http4s.dsl.io._\n\nimport memeid4s.http4s.implicits._\n\nobject UUIDParamDecoder extends QueryParamDecoderMatcher[UUID](\"uuid\")\n\nHttpRoutes.of[IO] { case GET -\u003e Root / \"user\" :? UUIDParamDecoder(uuid) =\u003e\n  Ok(s\"Hello, $uuid!\")\n}\n```\n\n##### Tapir\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-tapir\" % \"0.8.0\"\n```\n\nThe [Tapir](https://tapir.softwaremill.com/en/latest/) integration provides implicit instances for `Codec[UUID]` and `Schema[UUID]`, which allow using `UUID` as \ntype for query/path params or headers in endpoints. As well as enriching documentation when a `UUID` field is used.\n\n```scala\nimport memeid4s.tapir.implicits._\n\nimport sttp.tapir._\n\nendpoint.get.in(\"hello\" / path[UUID])\n```\n\n##### FUUID\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-fuuid\" % \"0.8.0\"\n```\n\nThe [FUUID](https://christopherdavenport.github.io/fuuid/) integration provides both semi (via extension methods) and auto conversions between memeid's `UUID` type and `FUUID`.\n\n```scala\nimport memeid4s.UUID\n\nimport io.chrisdavenport.fuuid.FUUID\nimport memeid4s.fuuid.syntax._\n\nval fuuid: FUUID = UUID.V4.random.toFUUID\n\nval uuid: UUID = fuuid.toUUID\n```\n\n```scala\nimport memeid4s.UUID\n\nimport io.chrisdavenport.fuuid.FUUID\nimport memeid4s.fuuid.auto._\n\ndef usingFUUID(fuuid: FUUID) = fuuid\n\ndef usingUUID(uuid: UUID) = uuid\n\nval uuid: UUID = UUID.V4.random\n\nval fuuid: FUUID = FUUID.fromUUID(java.util.UUID.randomUUID)\n\nusingFUUID(uuid)\nusingUUID(fuuid)\n```\n\n##### Cats \u0026 Cats-effect\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-cats\" % \"0.8.0\"\n```\n\nThe cats integration provides typeclass implementation for `UUID`, as well as effectful constructors for UUIDs for integration with programs that use `cats-effect`.\n\n###### Typeclasses\n\n```scala\nimport cats._\n\nimport memeid4s.cats.implicits._\nimport cats.effect.IO\n\nOrder[UUID]\nHash[UUID]\nEq[UUID]\nShow[UUID]\n```\n\n###### Constructors\n\n```scala\nUUID.random[IO]\n\nval namespace = UUID.V4.random\n\nUUID.v3[IO, String](namespace, \"my-secret-code\")\nUUID.v5[IO, String](namespace, \"my-secret-code\")\n```\n\n##### Scalacheck\n\n```scala\nlibraryDependencies += \"com.47deg\" %% \"memeid4s-scalacheck\" % \"0.8.0\"\n```\n\nThe scalacheck integration provides `Arbitrary` instances for the `UUID`, as well as for the different version classes.\n\n```scala\nimport org.scalacheck.Arbitrary.arbitrary\n\nimport memeid4s.scalacheck.arbitrary.instances._\n\narbitrary[UUID]\narbitrary[UUID.V1]\narbitrary[UUID.V2]\narbitrary[UUID.V3]\narbitrary[UUID.V4]\narbitrary[UUID.V5]\n```\n\n## Benchmarking\n\n[``sbt-jmh``](https://github.com/ktoso/sbt-jmh) is used for executing the benchmarking tests. \n\nThere are 2 kind of benchmarking:\n- ``runAvgtime``: Measures the average time it takes for the benchmark method to execute (a single execution). Generates the ``master.avgtime.csv`` file in the ``bench`` folder. \n- ``runThroughput``: Measures the number of operations per second, meaning the number of times per second your benchmark method could be executed. Generates the ``master.throughput.csv`` file in the ``bench`` folder.\n\n\n## References\n\n- [RFC 4122 - A Universally Unique Identifier](https://www.ietf.org/rfc/rfc4122.txt)\n- JVM [UUID type](https://docs.oracle.com/javase/7/docs/api/java/util/UUID.html)\n- [clj-uuid](https://github.com/danlentz/clj-uuid) Clojure implementation\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F47degrees%2Fmemeid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F47degrees%2Fmemeid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F47degrees%2Fmemeid/lists"}