Giter Club home page Giter Club logo

ocaml-cuid's Introduction

cuid

CUID generator for OCaml.

Ubuntu Workflow Status Windows Workflow Status MacOS Workflow Status Project License

For further information, please refer to http://usecuid.org

Installation

If available on OPAM, it's easily installed with:

$ opam install cuid

Otherwise, this library is also installable using Dune within this root directory:

$ dune install cuid

This cuid package is just an alias/wrapper around the cuid-unix package, there is a JavaScript-target package called cuid-jv as well.

Usage

As library:

let cuid = Cuid.generate ( )
(* cuid is "c00p6veue0000072slgr067a3", for example *)

There's also an implementation of CUID slugs. They fit in cases where collision-resistance is not important and when they are not generated too frequently. For instance, we can use them as URL suffixes for blog posts. To generate a CUID slug, just use:

let slug = Cuid.slug ( )
(* slug is "u90m0y0m", for example *)

For the cuid-unix internal package, the main module is called Cuid_unix, while the cuid-jv exposes the main module Cuid_jv.

Conclusion

PRs & issues are welcome. Have fun and imagine Sisyphus happy.

ocaml-cuid's People

Contributors

marcoonroad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

schutm

ocaml-cuid's Issues

Command-line tool must remember internal state (i.e, counter)

No matter how much time we call ocuidml, it will always return the same counter field (in the case, 0000). It doesn't seem right, honestly. We should figure out a way to persist the counter state among shell invocations for such command. Either through a sort of daemon server or local/user configuration might be reasonable. โœŒ๏ธ

Question: distribution of '__generate_random'

Hi,

please take into account I'm by far no crypto-expert, so please bear with me.

I understand the lines

ocaml-cuid/lib/cuid.ml

Lines 93 to 96 in f812a47

let fst = Cstruct.sub blob 0 9 |> __sum_then_mod ~basis:36 in
let snd = Cstruct.sub blob 9 9 |> __sum_then_mod ~basis:36 in
let trd = Cstruct.sub blob 18 9 |> __sum_then_mod ~basis:36 in
let fth = Cstruct.sub blob 27 9 |> __sum_then_mod ~basis:36 in
(and summation of 9 bytes) is to prevent a (slight) bias to 0, 1, 2 or 3.

However if I look at line

let res = ((fst + 1) * (snd + 1) * (trd + 1) * (fth + 1)) - 1 in
I'd think this also introduces a bias. Since a * b * c * d is the same as b * c * a * d (or whatever order you put them in) it looks to me the distribution is not fair. E.G. the MSB of the 1st byte is only set if a = b = c = d = 36, while the MSB of the second byte can be set in several different ways, where it doesn't matter whether which of a, b, c or d gets assigned a certain value (as long as the required values are assigned to the variable, but it doesn't matter to which variable the result will be the asme). However if we do (36 ^ 0) * a + (36 ^ 1) * b + (36 ^ 2) * c + (36 ^ 3) * d the MSB being set is directly dependent on the result of the crypto function. As a result the distribution should be fair in my opinion.

Any comments? Where is my reasoning going off?

Replace nocrypto dependency by mirage-crypto

This would make the cuid package portable and functional on Windows 10 environments too, mostly due the cryptographic secure PRNG & high-quality entropy sources support of mirage-crypto on all platforms (Unix, MacOS and Windows).

A bumping of minimal OCaml compiler version (v4.07.0) is needed as well due mirage-crypto-rng library requirements.

Cuid standard is deprecated.

Due to security concerns (which also exist in database auto-increment ids, uuid/guid, and most other id standrads), the Cuid standard is now deprecated in favor of Cuid2.

Compliance against Elliott's JS CUID library base conversion.

This OCaml library actually performs base-16 (i.e, hexadecimal) conversions. To comply how much possible with the original CUID JS library, we must stick to base-36 conversions.

The lines below are relevant to the context of this issue:

let maximum = int_of_float (36.0 ** 4.0)

...

let hexadecimal number = Printf.sprintf "%.08x" number

There's a mismatch, as it is easily seen. The maximum representation is under base-36, while the actual conversion runs under base-16.

Replace travis-ci builds by github-actions workflows

GH Actions is a far better integrated CI/CD solution. With that I would be able to setup different workflows for every platform (Ubuntu/Unix, MacOS and Windows) and track their build status in different markdown badges.

Also, Travis CI is charging open source projects' builds until maintainers enter in touch with Travis CI support team.

Timestamp implementation breaks monotonically increasing property.

It's all due integer overflow. Our implementation relies upon Unix.gettimeofday, which is out of the range of integer representation with OCaml (during the conversion through int_of_float). This OCaml conversion function doesn't detect overflows, and therefore it keeps going, increasing negatively too high floats into low/negative integers.

Possible solutions:

  • Use a different approach to take the system time.
  • Use a different representation for integers to be encoded into base-36 (maybe int 64-bits?)

The following piece of code is the context of this issue:

let timestamp ( ) =
  ( )
  |> Unix.gettimeofday
  |> int_of_float
  |> base36
  |> adjust8

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.