ulid 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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