Security News
Supply Chain Attack Detected in Solana's web3.js Library
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
com.47deg:memeid4s-circe_3
Advanced tools
Circe type-classes instances to enable decoding/encoding memeid's UUID values in JSON
memeid
is a JVM library for generating RFC-compliant Universal Unique Identifiers (UUIDs).
A universally unique identifier (UUID) is a 128-bit number used to identify information in computer systems.
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. -- Wikipedia article on UUIDs
The UUID type that ships with the JVM java.util.UUID
has a number of problems, namely:
This 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.
<dependency>
<groupId>com.47deg</groupId>
<artifactId>memeid</artifactId>
<version>0.7.0</version>
</dependency>
compile group: 'com.47deg', name: 'memeid', version: '0.7.0'
Add this to your build.sbt
file:
libraryDependencies += "com.47deg" %% "memeid4s" % "0.7.0"
The time-based (V1) variant of UUIDs is the fastest to generate. It uses a monotonic clock and node information to generate UUIDs.
import memeid4s.UUID
UUID.V1.next
The cryptographically random variant, equivalent to java.util.UUID/randomUUID
.
UUID.V4.random
Namespaced UUIDs are generated from a UUID (namespace) and a hashed value (name), V3 uses MD5 and V5 uses SHA1 hash.
val namespace = UUID.V1.next
We can now create UUIDs with the namespace and an arbitrary value as the name. It automatically works with Strings and UUIDs:
UUID.V3(namespace, "my-secret-code")
If you want to hash a custom type, you must provide an implicit memeid4s.digest.Digestible
instance.
import memeid4s.digest.Digestible
case class User(firstName: String, lastName: String)
implicit val digestibleUser: Digestible[User] =
(u: User) => u.firstName.getBytes ++ u.lastName.getBytes
The implicit instance is used to convert your type into a byte array for hashing:
UUID.V3(namespace, User("Federico", "García Lorca"))
SQUUIDs 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.
UUID.V4.squuid
memeid
provides conversion method between UUID
and java.util.UUID
through:
val j = java.util.UUID.fromString("a5fa7934-501c-46eb-9ea7-16de3086e6d8")
val u = memeid.UUID.fromString("8b4d1529-5fd0-4a91-8f4f-ceee10d1c060")
UUID.fromUUID(j)
// res5: UUID = a5fa7934-501c-46eb-9ea7-16de3086e6d8
u.asJava
// res6: java.util.UUID = 8b4d1529-5fd0-4a91-8f4f-ceee10d1c060
memeid
provides literal syntax with compile-time verification for UUIDs with the uuid
interpolator. To use it, add this to your build.sbt
:
libraryDependencies += "com.47deg" %% "memeid4s-literal" % "0.7.0"
We can now create UUIDs with literal syntax by importing memeid.literal._
import memeid4s.literal._
uuid"cb096727-6a82-4abd-bc79-fc92be8c5d88"
// res7: UUID = cb096727-6a82-4abd-bc79-fc92be8c5d88
Invalid UUID literals will fail at compile time:
uuid"not-a-uuid"
// error: invalid UUID: not-a-uuid
// uuid"not-a-uuid"
// ^^^^^^^^^^^^^^^^
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.
The Doobie integration allows you to use the UUID
type mapped to your database's UUID type.
libraryDependencies += "com.47deg" %% "memeid4s-doobie" % "0.7.0"
To have the UUID mappings available in scope you can import memeid.doobie.implicits
.
import memeid4s.doobie.implicits._
def select(uuid: UUID): Query0[UUID] =
sql"""SELECT id from test where id = $uuid""".query[UUID]
def insert(uuid: UUID): Update0 =
sql"""insert into test (id) values ($uuid)""".update
val example = uuid"58d61328-1b08-1171-1ee7-1283ed639e77"
{
for {
_ <- insert(example).run.transact(transactor)
u <- select(example).unique.transact(transactor)
} yield u
}.unsafeRunSync()
// res10: UUID = 58d61328-1b08-1171-1ee7-1283ed639e77
libraryDependencies += "com.47deg" %% "memeid4s-circe" % "0.7.0"
You can import memeid.circe.implicits
to have the Encoder
and Decoder
instances for UUID
in scope.
import io.circe.Json
import io.circe.Encoder
import io.circe.Decoder
import memeid4s.circe.implicits._
val uuid = uuid"58d61328-1b08-1171-1ee7-1283ed639e77"
val json = Json.fromString(uuid.toString)
Encoder[UUID].apply(uuid)
// res11: Json = JString(value = "58d61328-1b08-1171-1ee7-1283ed639e77")
Decoder[UUID].decodeJson(json)
// res12: Decoder.Result[UUID] = Right(
// value = 58d61328-1b08-1171-1ee7-1283ed639e77
// )
libraryDependencies += "com.47deg" %% "memeid4s-http4s" % "0.7.0"
Using UUID
companion object we can extract UUIDs from path parameters in URLs:
import cats.effect._
import org.http4s._
import org.http4s.dsl.io._
import memeid4s.UUID
HttpRoutes.of[IO] { case GET -> Root / "user" / UUID(uuid) =>
Ok(s"Hello, $uuid!")
}
The 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.
import cats.effect._
import org.http4s._
import org.http4s.dsl.io._
import memeid4s.http4s.implicits._
object UUIDParamDecoder extends QueryParamDecoderMatcher[UUID]("uuid")
HttpRoutes.of[IO] { case GET -> Root / "user" :? UUIDParamDecoder(uuid) =>
Ok(s"Hello, $uuid!")
}
libraryDependencies += "com.47deg" %% "memeid4s-tapir" % "0.7.0"
The Tapir integration provides implicit instances for Codec[UUID]
and Schema[UUID]
, which allow using UUID
as
type for query/path params or headers in endpoints. As well as enriching documentation when a UUID
field is used.
import memeid4s.tapir.implicits._
import sttp.tapir._
endpoint.get.in("hello" / path[UUID])
libraryDependencies += "com.47deg" %% "memeid4s-fuuid" % "0.7.0"
The FUUID integration provides both semi (via extension methods) and auto conversions between memeid's UUID
type and FUUID
.
import memeid4s.UUID
import io.chrisdavenport.fuuid.FUUID
import memeid4s.fuuid.syntax._
val fuuid: FUUID = UUID.V4.random.toFUUID
val uuid: UUID = fuuid.toUUID
import memeid4s.UUID
import io.chrisdavenport.fuuid.FUUID
import memeid4s.fuuid.auto._
def usingFUUID(fuuid: FUUID) = fuuid
def usingUUID(uuid: UUID) = uuid
val uuid: UUID = UUID.V4.random
val fuuid: FUUID = FUUID.fromUUID(java.util.UUID.randomUUID)
usingFUUID(uuid)
usingUUID(fuuid)
libraryDependencies += "com.47deg" %% "memeid4s-cats" % "0.7.0"
The cats integration provides typeclass implementation for UUID
, as well as effectful constructors for UUIDs for integration with programs that use cats-effect
.
import cats._
import memeid4s.cats.implicits._
import cats.effect.IO
Order[UUID]
Hash[UUID]
Eq[UUID]
Show[UUID]
UUID.random[IO]
val namespace = UUID.V4.random
UUID.v3[IO, String](namespace, "my-secret-code")
UUID.v5[IO, String](namespace, "my-secret-code")
libraryDependencies += "com.47deg" %% "memeid4s-scalacheck" % "0.7.0"
The scalacheck integration provides Arbitrary
instances for the UUID
, as well as for the different version classes.
import org.scalacheck.Arbitrary.arbitrary
import memeid4s.scalacheck.arbitrary.instances._
arbitrary[UUID]
arbitrary[UUID.V1]
arbitrary[UUID.V2]
arbitrary[UUID.V3]
arbitrary[UUID.V4]
arbitrary[UUID.V5]
sbt-jmh
is used for executing the benchmarking tests.
There are 2 kind of benchmarking:
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.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.FAQs
Circe type-classes instances to enable decoding/encoding memeid's UUID values in JSON
We found that com.47deg:memeid4s-circe_3 demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.