GithubHelp home page GithubHelp logo

zelark / nano-id Goto Github PK

View Code? Open in Web Editor NEW
190.0 4.0 9.0 68 KB

A unique string ID generator for Clojure and ClojureScript (・_・)ノ

License: MIT License

Clojure 88.01% Java 11.99%
clojure clojurescript secure-random-generator id-generator

nano-id's Introduction

nano-id

A tiny, secure, URL-friendly unique string ID generator for Clojure and ClojureScript.

  • Secure. It uses cryptographically strong random APIs.
  • Compact. It uses a larger alphabet than UUID (A-Za-z0-9_-). So ID size was reduced from 36 to 21 symbols.
  • URL-Friendly. It uses only URL-friendly characters. Perfect for unique identifiers in web applications.
clj -Sdeps '{:deps {nano-id/nano-id {:mvn/version "1.1.0"}}}'

(require '[nano-id.core :refer [nano-id]])
(nano-id) ;; => "trxwfoC8mqB3Q8Wrdq4OQ"

Clojars Project cljdoc badge clojure tests

Benchmark

$ lein bench

## Actually, you will get more detailed info, this is summary of 3 runs.

UUID               0.29µs 0.29µs 0.30µs
nano-id            0.43µs 0.44µs 0.43µs
jnanoid            0.64µs 0.66µs 0.65µs
nano-id (custom)   0.62µs 0.62µs 0.62µs
jnanoid (custom)   0.65µs 0.65µs 0.68µs

Configuration:

  • MacBook Pro (16-inch, 2019), 2,3 GHz 8-Core Intel Core i9, 32 GB 2667 MHz DDR4;
  • OpenJDK Runtime Environment Temurin-11.0.22+7 (build 11.0.22+7);
  • Clojure 1.11.1.

Installation

Clojure CLI

nano-id/nano-id {:mvn/version "1.1.0"}

Leiningen or Boot

[nano-id "1.1.0"]

Usage

The default implementation uses 64-character alphabet and generates 21-character IDs.

user=> (require '[nano-id.core :refer [nano-id]])
nil

user=> (nano-id)
"NOBHihn110UuXbF2JiKxT"

If you want to reduce the ID size (and increase collision probability), you can pass the size as an argument.

user=> (nano-id 10)
"N2g6IlJP0l"

Don’t forget to check the safety of your ID size via collision probability calculator.

IE

For IE support, you need to add crypto alias:

(ns your-app.polyfills)

(when-not (exists? js/crypto)
  (set! js/crypto js/msCrypto))
(ns your-app.core
  (:require [your-app.polyfills]
            [nano-id.core :refer [nano-id]]))

Node.js

If your target is node, use @peculiar/webcrypto polyfill:

(ns your-app.polyfills
  (:require ["@peculiar/webcrypto" :refer [Crypto]]))

(set! js/crypto (Crypto.))
(ns your-app.core
  (:require [your-app.polyfills]
            [nano-id.core :refer [nano-id]]))

Custom ID generator

If for whatever reason the default implementation doesn't fit your project, you can build your own ID generator just passing your alphabet and ID size in custom function. It will give you back a new generator:

user=> (require '[nano-id.core :refer [custom]])
nil

user=> (def my-nano-id (custom ".-" 6))
#'user/my-nano-id

user=> (my-nano-id)
"-.---."

Also you can provide your random bytes generator. In the example below we use this feature to encode the current time:

(let [alphabet "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
      time-gen (fn [n]
                 (->> (quot (System/currentTimeMillis) 1000)
                      (iterate #(unsigned-bit-shift-right % 6))
                      (take n)
                      reverse
                      byte-array))
      time-id  (custom alphabet 6 time-gen)]
  (time-id))
"0TfMui"

This encodes current time using a lexicographical alphabet.

Tools

Other implementations

You can find implementations in other programming languages here.

Inspired by

Nano ID.

nano-id's People

Contributors

julienmalige avatar prestancedesign avatar zelark avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

nano-id's Issues

CLJS: Strings dont have a length attribute

Ran in to this error when I try to use a custom generator.

(def hex-id-generator (generate "0123456789abcdef"))

Exception

Uncaught TypeError: id.length is not a function
    at nano_id.custom.generate.cljs$core$IFn$_invoke$arity$2 (custom.cljc?rel=1531759015549:22)
    at my_tool$events$generate_system_key (events.cljs?rel=1531759024127:14)
    at events.cljs?rel=1531759024127:96
    at std_interceptors.cljc?rel=1531759023484:115
    at re_frame$std_interceptors$db_handler__GT_interceptor_$_db_handler_before (std_interceptors.cljc?rel=1531759023484:111)
    at re_frame$interceptor$invoke_interceptor_fn (interceptor.cljc?rel=1531759014576:68)
    at re_frame$interceptor$invoke_interceptors (interceptor.cljc?rel=1531759014576:106)
    at re_frame$interceptor$execute (interceptor.cljc?rel=1531759014576:199)
    at re_frame$events$handle (events.cljc?rel=1531759022762:65)
    at re_frame.router.EventQueue.re_frame$router$IEventQueue$_process_1st_event_in_queue$arity$1 (router.cljc?rel=1531759022973:178)
    at re_frame$router$_process_1st_event_in_queue (router.cljc?rel=1531759022973:84)
    at re_frame.router.EventQueue.re_frame$router$IEventQueue$_run_queue$arity$1 (router.cljc?rel=1531759022973:197)
    at re_frame$router$_run_queue (router.cljc?rel=1531759022973:86)
    at router.cljc?rel=1531759022973:145
    at re_frame.router.EventQueue.re_frame$router$IEventQueue$_fsm_trigger$arity$3 (router.cljc?rel=1531759022973:168)
    at re_frame$router$_fsm_trigger (router.cljc?rel=1531759022973:80)
    at router.cljc?rel=1531759022973:186

Environment;

[org.clojure/clojurescript "1.10.238"]
                 [reagent "0.7.0"]
                 [re-frame "0.10.5"]
                 [nano-id "0.9.2"]
                 [com.andrewmcveigh/cljs-time "0.5.2"]

Who is using nano-id?

Since new 1.0.0 version is going out soon, I wonder who's using nano-id? So if you use it in prod or just for hobby project, please drop a message below. I'd like to add a list to readme.

Also you might consider to start using it once 1.0.0 is released. ٩(◕‿◕。)۶

UPD: nano-id 1.0.0 was released. Give it a try.

[custom.generate] building string by adding characters to beginning of line

A goal is generating IDs in lexicographical order. And there are 2 ways to reach for the goal:

  1. To do like topic says;
  2. Producing numbers in example below in reverse order:
(let [alphabet "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"
      time-gen (fn [n] (take n (iterate #(bit-shift-right % 6)
                                        (quot (System/currentTimeMillis) 1000))))
      time-id  (generate alphabet time-gen)]
  (time-id 6))

API 2.0

Let’s update the library to be compatible with the latest Nano ID 2.0:

  • Replace ~ to - in default alphabet
  • Add non-secure fast generator
  • Async API?

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.