ulid 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc065154adc250d260ea69bdbf3b4f30a760ab6b
4
+ data.tar.gz: 0012c1a18390f4e82cdc1a60de330dc2009d89b7
5
+ SHA512:
6
+ metadata.gz: f019f4a68180707cbc28c4cd5ee3464d7be861997400879b6a6bdb7981991f8c27b385a80ab8b6868a8cd4b4c0d50b30b8d6091874560fa7f8148638589937b1
7
+ data.tar.gz: 43e5d04f97ed8a34720bf1e41af6f85369a5da471e76b0166965520399e98ec37adf7e710b4f4f6631fed0c6d7a1c0adefc6676bff5c3c3a11f58a613d49e867
data/.gitignore ADDED
@@ -0,0 +1,50 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ ## Specific to RubyMotion:
17
+ .dat*
18
+ .repl_history
19
+ build/
20
+ *.bridgesupport
21
+ build-iPhoneOS/
22
+ build-iPhoneSimulator/
23
+
24
+ ## Specific to RubyMotion (use of CocoaPods):
25
+ #
26
+ # We recommend against adding the Pods directory to your .gitignore. However
27
+ # you should judge for yourself, the pros and cons are mentioned at:
28
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
29
+ #
30
+ # vendor/Pods/
31
+
32
+ ## Documentation cache and generated files:
33
+ /.yardoc/
34
+ /_yardoc/
35
+ /doc/
36
+ /rdoc/
37
+
38
+ ## Environment normalization:
39
+ /.bundle/
40
+ /vendor/bundle
41
+ /lib/bundler/man/
42
+
43
+ # for a library or gem, you might want to ignore these files since the code is
44
+ # intended to run in multiple environments; otherwise, check them in:
45
+ # Gemfile.lock
46
+ # .ruby-version
47
+ # .ruby-gemset
48
+
49
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-pg_sync.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem "bundler", "~> 1.12.5"
8
+ gem "rake", "~> 10.0"
9
+ gem "pry-byebug"
10
+ end
11
+
12
+ group :test do
13
+ gem "minitest"
14
+ gem "mocha"
15
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ulid (0.0.1)
5
+ sysrandom (>= 1.0.0, < 2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ byebug (9.0.5)
11
+ coderay (1.1.1)
12
+ metaclass (0.0.4)
13
+ method_source (0.8.2)
14
+ minitest (5.9.0)
15
+ mocha (1.1.0)
16
+ metaclass (~> 0.0.1)
17
+ pry (0.10.4)
18
+ coderay (~> 1.1.0)
19
+ method_source (~> 0.8.1)
20
+ slop (~> 3.4)
21
+ pry-byebug (3.4.0)
22
+ byebug (~> 9.0)
23
+ pry (~> 0.10)
24
+ rake (10.5.0)
25
+ slop (3.6.0)
26
+ sysrandom (1.0.2)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ bundler (~> 1.12.5)
33
+ minitest
34
+ mocha
35
+ pry-byebug
36
+ rake (~> 10.0)
37
+ ulid!
38
+
39
+ BUNDLED WITH
40
+ 1.12.5
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Rafael Sales
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # ulid
2
+ Universally Unique Lexicographically Sortable Identifier implementation for Ruby
3
+
4
+ <h1 align="center">
5
+ <br>
6
+ <br>
7
+ <img width="360" src="logo.png" alt="ulid">
8
+ <br>
9
+ <br>
10
+ <br>
11
+ </h1>
12
+
13
+ # Universally Unique Lexicographically Sortable Identifier
14
+
15
+ UUID can be suboptimal for many uses-cases because:
16
+
17
+ - It isn't the most character efficient way of encoding 128 bits of randomness
18
+ - The string format itself is apparently based on the original MAC & time version (UUIDv1 from Wikipedia)
19
+ - It provides no other information than randomness
20
+
21
+ Instead, herein is proposed ULID:
22
+
23
+ - 128-bit compatibility with UUID
24
+ - 1.21e+24 unique ULIDs per millisecond
25
+ - Lexicographically sortable!
26
+ - Canonically encoded as a 26 character string, as opposed to the 36 character UUID
27
+ - Uses Crockford's base32 for better efficiency and readability (5 bits per character)
28
+ - Case insensitive
29
+ - No special characters (URL safe)
30
+
31
+ ### Installation
32
+
33
+ ```
34
+ gem install ulid
35
+ ```
36
+
37
+ ### Usage
38
+
39
+ ```ruby
40
+ require 'ulid'
41
+
42
+ ULID.generate // 01ARZ3NDEKTSV4RRFFQ69G5FAV
43
+ ```
44
+
45
+ ## Specification
46
+
47
+ Below is the current specification of ULID as implemented in this repository. *Note: the binary format has not been implemented.*
48
+
49
+ ```
50
+ 01AN4Z07BY 79KA1307SR9X4MV3
51
+
52
+ |----------| |----------------|
53
+ Timestamp Randomness
54
+ 10 chars 16 chars
55
+ 48bits 80bits
56
+ base32 base32
57
+ ```
58
+
59
+ ### Components
60
+
61
+ **Timestamp**
62
+ - 48 bit integer
63
+ - UNIX-time in milliseconds
64
+ - Won't run out of space till the year 10895 AD.
65
+
66
+ **Randomness**
67
+ - 80 bits
68
+ - Cryptographically secure source of randomness, if possible
69
+
70
+ ### Sorting
71
+
72
+ The left-most character must be sorted first, and the right-most character sorted last. The default ASCII order is used for sorting.
73
+
74
+ ### Binary Layout and Byte Order
75
+
76
+ The components are encoded as 16 octets. Each component is encoded with the Most Significant Byte first (network byte order).
77
+
78
+ ```
79
+ 0 1 2 3
80
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
81
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82
+ | 32_bit_uint_time_low |
83
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84
+ | 16_bit_uint_time_high | 16_bit_uint_random |
85
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86
+ | 32_bit_uint_random |
87
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88
+ | 32_bit_uint_random |
89
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90
+ ```
91
+
92
+ ### String Representation
93
+
94
+ ```
95
+ ttttttttttrrrrrrrrrrrrrrrr
96
+
97
+ where
98
+ t is Timestamp
99
+ r is Randomness
100
+ ```
101
+
102
+ ## Test Suite
103
+
104
+ ```
105
+ # TODO
106
+ ```
107
+
108
+ ## Performance
109
+
110
+ ```
111
+ # TODO
112
+ ```
113
+
114
+ ```
115
+ ulid
116
+ 336,331,131 op/s » encodeTime
117
+ 102,041,736 op/s » encodeRandom
118
+ 17,408 op/s » generate
119
+
120
+
121
+ Suites: 1
122
+ Benches: 3
123
+ Elapsed: 7,285.75 ms
124
+ ```
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs += ["spec", "lib"]
6
+ t.test_files = FileList['spec/**/*_spec.rb']
7
+ end
data/lib/ulid.rb ADDED
@@ -0,0 +1,7 @@
1
+ module ULID
2
+ def self.random_create
3
+ Generator.new.random_create
4
+ end
5
+ end
6
+
7
+ Dir.glob(File.join(File.dirname(__FILE__), "/ulid/**/*.rb")).sort.each { |f| require f }
@@ -0,0 +1,34 @@
1
+ require 'sysrandom'
2
+
3
+ module ULID
4
+ class Generator
5
+ ENCODING = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'
6
+
7
+ def random_create
8
+ encode_time(milliseconds_since_epoch, 10) + encode_random(16)
9
+ end
10
+
11
+ private
12
+
13
+ def encode_time(now, length)
14
+ length.times.reduce("") do |output|
15
+ mod = now % ENCODING.length
16
+ now = (now - mod) / ENCODING.length
17
+
18
+ output << ENCODING[mod]
19
+ end
20
+ end
21
+
22
+ def encode_random(length)
23
+ length.times.reduce("") do |output|
24
+ random = Sysrandom.random_number(ENCODING.length)
25
+
26
+ output << ENCODING[random]
27
+ end
28
+ end
29
+
30
+ def milliseconds_since_epoch
31
+ (Time.now.to_f * 1000).to_i
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module ULID
2
+ VERSION = '0.0.1'
3
+ end
data/logo.png ADDED
Binary file
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe ULID do
4
+ it "works" do
5
+ ulid = ULID.random_create
6
+ ulid.length.must_equal 26
7
+ end
8
+ end
9
+
@@ -0,0 +1,5 @@
1
+ require 'pry'
2
+ require 'minitest/autorun'
3
+ require 'minitest/pride'
4
+ require 'mocha/mini_test'
5
+ require 'ulid'
data/ulid.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ulid/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ulid"
8
+ spec.version = ULID::VERSION
9
+ spec.authors = ["Rafael Sales"]
10
+ spec.email = ["rafaelcds@gmail.com"]
11
+ spec.summary = %q{Universally Unique Lexicographically Sortable Identifier implementation for Ruby}
12
+ spec.homepage = "https://github.com/rafaelsales/ulid"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "sysrandom", ">= 1.0.0", "< 2.0"
21
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ulid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Rafael Sales
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sysrandom
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ description:
34
+ email:
35
+ - rafaelcds@gmail.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - ".gitignore"
41
+ - Gemfile
42
+ - Gemfile.lock
43
+ - LICENSE
44
+ - README.md
45
+ - Rakefile
46
+ - lib/ulid.rb
47
+ - lib/ulid/generator.rb
48
+ - lib/ulid/version.rb
49
+ - logo.png
50
+ - spec/lib/ulid_spec.rb
51
+ - spec/spec_helper.rb
52
+ - ulid.gemspec
53
+ homepage: https://github.com/rafaelsales/ulid
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.5.1
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Universally Unique Lexicographically Sortable Identifier implementation for
77
+ Ruby
78
+ test_files:
79
+ - spec/lib/ulid_spec.rb
80
+ - spec/spec_helper.rb