• Stars
    star
    16
  • Rank 1,269,359 (Top 26 %)
  • Language
    Crystal
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Crystal implementation of K-Sortable Globally Unique IDs

ksuid.cr CI Releases License

This library implements the K-Sortable Globally Unique IDs from Segment. The original readme for the Go version of KSUID does a great job of explaining what they are and how they should be used, so it is excerpted here.

See also the article called A Brief History of the UUID.

What is a KSUID?

KSUID is for K-Sortable Unique IDentifier. It's a way to generate globally unique IDs similar to RFC 4122 UUIDs, but contain a time component so they can be "roughly" sorted by time of creation. The remainder of the KSUID is randomly generated bytes.

Why use KSUIDs?

Distributed systems often require unique IDs. There are numerous solutions out there for doing this, so why KSUID?

1. Sortable by Timestamp

Unlike the more common choice of UUIDv4, KSUIDs contain a timestamp component that allows them to be roughly sorted by generation time. This is obviously not a strong guarantee as it depends on wall clocks, but is still incredibly useful in practice.

2. No Coordination Required

Snowflake IDs and derivatives require coordination, which significantly increases the complexity of implementation and creates operations overhead. While RFC 4122 UUIDv1s do have a time component, there aren't enough bytes of randomness to provide strong protections against duplicate ID generation.

KSUIDs use 128-bits of pseudorandom data, which provides a 64-times larger number space than the 122-bits in the well-accepted RFC 4122 UUIDv4 standard. The additional timestamp component drives down the extremely rare chance of duplication to the point of near physical infeasibility, even assuming extreme clock skew (> 24-hours) that would cause other severe anomalies.

3. Lexographically Sortable, Portable Representations

The binary and string representations are lexicographically sortable, which allows them to be dropped into systems which do not natively support KSUIDs and retain their k-sortable characteristics.

The string representation is that it is base62-encoded, so that they can "fit" anywhere alphanumeric strings are accepted.

How do they work?

KSUIDs are 20-bytes: a 32-bit unsigned integer UTC timestamp and a 128-bit randomly generated payload. The timestamp uses big-endian encoding, to allow lexicographic sorting. The timestamp epoch is adjusted to May 13th, 2014, providing over 100 years of useful life starting at UNIX epoch + 14e8. The payload uses a cryptographically-strong pseudorandom number generator.

The string representation is fixed at 27-characters encoded using a base62 encoding that also sorts lexicographically.

Installation

Add this to your application's shard.yml:

dependencies:
  ksuid:
    github: Sija/ksuid.cr

Usage

require "ksuid"

To generate a random KSUID for the present time, use:

ksuid = KSUID.new

To generate a KSUID for a specific timestamp, use:

ksuid = KSUID.new(time: time) # where *time* is a `Time` object

If you need to parse a KSUID from a string that you received, use the conversion method:

ksuid = KSUID.from(base62_string)

If you need to interpret a series of bytes that you received, use the conversion method:

ksuid = KSUID.from(bytes)

JSON

require "ksuid/json"

class Example
  include JSON::Serializable

  property id : KSUID
end

example = Example.from_json(%({"id": "aWgEPTl1tmebfsQzFP4bxwgy80V"}))
# => #<Example:0x10a8723c0 @id=KSUID(aWgEPTl1tmebfsQzFP4bxwgy80V)>

example.to_json
# => "{\"id\":\"aWgEPTl1tmebfsQzFP4bxwgy80V\"}"

YAML

require "ksuid/yaml"

class Example
  include YAML::Serializable

  property id : KSUID
end

example = Example.from_yaml(%(---\nid: aWgEPTl1tmebfsQzFP4bxwgy80V\n))
# => #<Example:0x10a8723c0 @id=KSUID(aWgEPTl1tmebfsQzFP4bxwgy80V)>

example.to_yaml
# => "---\nid: aWgEPTl1tmebfsQzFP4bxwgy80V\n"

Contributing

  1. Fork it (https://github.com/Sija/ksuid.cr/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • @Sija Sijawusz Pur Rahnama - creator, maintainer

More Repositories

1

garb

A Ruby wrapper for the Google Analytics API
Ruby
147
star
2

raven.cr

Raven is a Crystal client for Sentry
Crystal
120
star
3

debug.cr

Debug macro for Crystal
Crystal
92
star
4

ipaddress.cr

A Crystal library to handle IPv4 and IPv6 addresses in a modern and productive way.
Crystal
43
star
5

retriable.cr

Retriable.cr is a simple DSL to retry failed code blocks
Crystal
38
star
6

any_hash.cr

Better JSON::Any for Crystal
Crystal
33
star
7

blurhash.cr

A pure Crystal implementation of BlurHash algorithm
Crystal
22
star
8

backtracer.cr

Crystal shard aiming to assist with parsing backtraces into a structured form.
Crystal
16
star
9

crystal-dash-docset

Dash docset generator for Crystal
Shell
16
star
10

gphoto2.cr

Crystal shard wrapping libgphoto2
Crystal
15
star
11

climate.cr

Tiny tool to make your CLI output 🌈 coloured
Crystal
14
star
12

serialport.cr

Crystal bindings for libserialport: cross-platform library for accessing serial ports.
Crystal
12
star
13

base62.cr

Base62 encoder/decoder for Crystal
Crystal
10
star
14

crystal-environment

Crystal::Environment
Crystal
7
star
15

gphoto2-web

Web API for libgphoto2
Crystal
6
star
16

gitbook2pdf

CLI utility to turn a published GitBook website into a collection of PDFs for offline reading
JavaScript
3
star
17

Gizmo

Quick'n'easy file based content management system
PHP
2
star
18

jsonl.cr

Crystal shard for handling JSONL (JSON Lines) parsing
Crystal
1
star
19

Sija

1
star
20

coffeeshop

Unfinished Coffee powered, Express based framework for Node.js
CoffeeScript
1
star
21

kPilot.w3

Web backend for kPilot Konnekt IM plugin.
PHP
1
star
22

markdown

PSR-0 compliant Markdown library
PHP
1
star
23

seedling

Rails 3 plugin for a database-independent YAML seeds import/export.
Ruby
1
star
24

MazeSolver

Maze solver written in PHP 5.
PHP
1
star
25

kZmieniacz

kZmieniacz to wtyczka dla komunikatora Konnekt pozwalająca zmieniać status opisowy jednocześnie we wszystkich wykorzystywanych sieciach.
C++
1
star
26

photoindex

Ancient, self-contained php gallery script.
PHP
1
star
27

resque-dry

Ruby
1
star
28

swift

Never finished C++ templating engine.
C++
1
star
29

kulturadaru

PHP
1
star
30

smartypants

PSR-0 compliant Smartypants library
PHP
1
star
31

kAway

Away system for the Konnekt IM
C++
1
star
32

git-rewrite-author

CLI tool for rewriting author/committer history of a git repository
Crystal
1
star
33

QRKit

QR Reader in Objective C ported from zxing
C++
1
star
34

thumb-cutter

Blazingly fast thumb cutting and image juggling middleware for any node/express.js kitchen sink
JavaScript
1
star
35

sunspot_resque

Sunspot-Resque Session Proxy
Ruby
1
star
36

jquery.clamp

JavaScript with CSS "overflow: ellipsis" line clamping, as jQuery plugin and standalone AMD module
CoffeeScript
1
star