uxid 0.0.1 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed3424777407d1f5ba89a397eff5afef6856b76f2a297465a5f8f2e8bdb780ea
4
- data.tar.gz: 7da99c1c18ff54126c116c2cc8acc3ba8dccf3cff4e2c5de40fbdfd02b2f4ff6
3
+ metadata.gz: 329b2b3ae00dc22cfc6a32ce123ad4f22a1211cc2d1851d1797211b838b59983
4
+ data.tar.gz: 586e48ce10bd900cf51a1fafc363640443d2f22e6ac845ddcaac85ae810467bc
5
5
  SHA512:
6
- metadata.gz: 7857a6c7493e2bf50428f87d806901e900a3772ed1bfa276c8e56feb0ea37715aac9836f64032c807f4e12bfa906e2b9cd49e521a144d0f2e23a5f82cb58c825
7
- data.tar.gz: f913e3af0c61847e0c8eca11497f1d7d51a928d6c666baea7762f73f2c9d14a32d18bb4db308b13b68ab3acda2e451eb597f90fca66e3ed9465007501f125812
6
+ metadata.gz: a5516fd55ea9f94f64c4a7535b4d1bb751ba729021aad89e28a47fd23b7adb42183d2267374a28badacb0aab704fd591eb22a7d7f4ae0d3a589eb0ee04b2c384
7
+ data.tar.gz: a19e5b88e3e0d2b88931bfb146d2323595e848dbf4d6675726afc476c4a1a1a3810870bd1e34e7f92bbbf1b8014419bf97a7bebd5c3392f4a7f624043f56a555
@@ -0,0 +1,72 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ danger:
10
+ runs-on: ubuntu-latest
11
+ if: github.event_name == 'pull_request' # only run pull request when multiple trigger workflow
12
+ steps:
13
+ - name: Checkout Repo
14
+ uses: actions/checkout@v2
15
+
16
+ - name: Setup Ruby
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ ruby-version: '2.6'
20
+
21
+ - name: Cache Ruby Gems
22
+ uses: actions/cache@v2
23
+ with:
24
+ path: vendor/bundle
25
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
26
+ restore-keys: |
27
+ ${{ runner.os }}-gems-
28
+
29
+ - name: Bundle Install
30
+ run: |
31
+ bundle config path vendor/bundle
32
+ bundle install --jobs 4 --retry 3
33
+
34
+ - name: Danger linting
35
+ uses: MeilCli/danger-action@v5
36
+ with:
37
+ plugins_file: Gemfile
38
+ install_path: vendor/bundle
39
+ danger_file: Dangerfile
40
+ danger_id: danger-pr
41
+ env:
42
+ DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
43
+
44
+ tests:
45
+ runs-on: ubuntu-latest
46
+ if: github.event_name == 'pull_request' # only run pull request when multiple trigger workflow
47
+ steps:
48
+ - name: Checkout Repo
49
+ uses: actions/checkout@v2
50
+
51
+ - name: Setup Ruby
52
+ uses: actions/setup-ruby@v1
53
+ with:
54
+ ruby-version: '2.6'
55
+
56
+ - name: Cache Ruby Gems
57
+ uses: actions/cache@v2
58
+ with:
59
+ path: vendor/bundle
60
+ key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
61
+ restore-keys: |
62
+ ${{ runner.os }}-gems-
63
+
64
+ - name: Bundle Install
65
+ run: |
66
+ bundle config path vendor/bundle
67
+ bundle install --jobs 4 --retry 3
68
+
69
+ - name: Run Tests
70
+ run: |
71
+ bundle config path vendor/bundle
72
+ bundle exec rake test
@@ -0,0 +1,43 @@
1
+ # Custom files
2
+
3
+ # Compiled source
4
+ *.com
5
+ *.class
6
+ *.dll
7
+ *.exe
8
+ *.o
9
+ *.so
10
+
11
+ # Packages
12
+ #
13
+ # It's better to unpack these files and commit the raw source
14
+ # git has its own built in compression methods
15
+ *.7z
16
+ *.dmg
17
+ *.gz
18
+ *.iso
19
+ *.jar
20
+ *.rar
21
+ *.tar
22
+ *.zip
23
+
24
+ # Logs and databases
25
+ *.log
26
+ *.sql
27
+ *.sqlite
28
+
29
+ # OS generated files #
30
+ .DS_Store
31
+ .DS_Store?
32
+ ._*
33
+ .Spotlight-V100
34
+ .Trashes
35
+ ehthumbs.db
36
+ Thumbs.db
37
+
38
+ # Editor-made files
39
+ *.swp
40
+
41
+ #===== Ruby =====
42
+ *.gem
43
+ reports/
@@ -0,0 +1,103 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5
3
+ DisabledByDefault: true
4
+ Exclude:
5
+ - pkg/**/*.rb
6
+ - test/spec/**/*.rb
7
+
8
+ Bundler/DuplicatedGem:
9
+ Enabled: true
10
+ Lint:
11
+ Enabled: true
12
+ Security:
13
+ Enabled: true
14
+
15
+ # Single quotes being faster is hardly measurable and only affects parse time.
16
+ # Enforcing double quotes reduces the times where you need to change them
17
+ # when introducing an interpolation. Use single quotes only if their semantics
18
+ # are needed.
19
+ Style/StringLiterals:
20
+ EnforcedStyle: double_quotes
21
+ Exclude:
22
+ - lib/riddler/protobuf/*_pb.rb
23
+
24
+ # Seattle style
25
+ Style/MethodDefParentheses:
26
+ EnforcedStyle: require_no_parentheses
27
+
28
+ # Seattle style
29
+ Style/MethodCallWithoutArgsParentheses:
30
+ Enabled: true
31
+
32
+ # Seattle style
33
+ Style/MethodCallWithArgsParentheses:
34
+ Enabled: true
35
+ EnforcedStyle: omit_parentheses
36
+ AllowParenthesesInChaining: true
37
+ IgnoredMethods:
38
+ - watch
39
+
40
+ Style/SpecialGlobalVars:
41
+ Enabled: false
42
+
43
+ Layout/FirstArrayElementIndentation:
44
+ Enabled: true
45
+ EnforcedStyle: consistent
46
+
47
+ Style/Lambda:
48
+ Enabled: true
49
+ EnforcedStyle: literal
50
+
51
+ # Allow regex argument in Seattle style
52
+ Lint/AmbiguousRegexpLiteral:
53
+ Enabled: false
54
+
55
+ # Allow block argument in Seattle style
56
+ Lint/AmbiguousOperator:
57
+ Enabled: false
58
+
59
+ Layout/SpaceInsideHashLiteralBraces:
60
+ Enabled: true
61
+ EnforcedStyleForEmptyBraces: no_space
62
+ EnforcedStyle: no_space
63
+
64
+ Layout/FirstHashElementIndentation:
65
+ Enabled: true
66
+ EnforcedStyle: consistent
67
+
68
+ Layout/CaseIndentation:
69
+ Enabled: true
70
+ EnforcedStyle: end
71
+
72
+ Layout/EndAlignment:
73
+ Enabled: true
74
+ EnforcedStyleAlignWith: variable
75
+
76
+ Layout/SpaceAroundBlockParameters:
77
+ Enabled: true
78
+
79
+ Layout/SpaceBeforeBlockBraces:
80
+ Enabled: true
81
+
82
+ Layout/SpaceInsideBlockBraces:
83
+ Enabled: true
84
+
85
+ Layout/LineLength:
86
+ Enabled: true
87
+ Max: 120
88
+ Exclude:
89
+ - lib/riddler/protobuf/*_pb.rb
90
+
91
+ Metrics/ClassLength:
92
+ Enabled: true
93
+ Max: 200
94
+ Exclude:
95
+ - test/**/*.rb
96
+
97
+ Lint/SuppressedException:
98
+ Exclude:
99
+ - lib/tasks/**/*.rake
100
+
101
+ Lint/Debugger:
102
+ Exclude:
103
+ - test/**/*
@@ -0,0 +1,8 @@
1
+ SimpleCov.start do
2
+ coverage_dir "reports/coverage"
3
+
4
+ add_filter "/config/"
5
+ add_filter "/lib/tasks/"
6
+
7
+ track_files "lib/**/*.rb"
8
+ end
@@ -1,3 +1,37 @@
1
- ### 0.0.1 / 2020-06-17
1
+ ### Upcoming
2
+
3
+ * (Nothing yet)
4
+
5
+
6
+ ### 0.2.3 / 2020-11-29
7
+
8
+ * Updates project URL
9
+
10
+
11
+ ### 0.2.2 / 2020-11-25
12
+
13
+ * Uses Ruby path for Gemspec homepage
14
+ * Adds more tests around generation using size option
15
+
16
+
17
+ ### 0.2.1 / 2020-11-25
18
+
19
+ * Removes extra chars from generation
20
+ * Adds tests around generation of sizes
21
+
22
+
23
+ ## 0.2.0 / 2020-11-24
24
+
25
+ * Deprecates :size option with integers
26
+ * Adds T-Shirt sizes (:size option)
27
+ * Adds :rand_size option (:rand_size option)
28
+
29
+
30
+ ## 0.1.0 / 2020-11-08
31
+
32
+ * Adds basic UXID generation
33
+
34
+
35
+ ## 0.0.1 / 2020-06-17
2
36
 
3
37
  * Birthday!
@@ -0,0 +1,5 @@
1
+ # Check format of commit message
2
+ commit_lint.check fail: :all
3
+
4
+ # Make it more obvious that a PR is a work in progress and shouldn't be merged yet
5
+ warn "PR is classed as Work in Progress" if github.pr_title.include? "[WIP]"
data/Gemfile CHANGED
@@ -3,5 +3,13 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in uxid.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 12.0"
6
+ gem "danger"
7
+ gem "danger-commit_lint"
7
8
  gem "minitest", "~> 5.0"
9
+ gem "minitest-focus"
10
+ gem "minitest-reporters"
11
+ gem "pry-nav"
12
+ gem "rake", "~> 12.0"
13
+ gem "rubycritic", require: false
14
+ gem "rubocop"
15
+ gem "simplecov", require: false
@@ -1,21 +1,171 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- uxid (0.0.1)
4
+ uxid (0.2.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ addressable (2.7.0)
10
+ public_suffix (>= 2.0.2, < 5.0)
11
+ ansi (1.5.0)
12
+ ast (2.4.1)
13
+ axiom-types (0.1.1)
14
+ descendants_tracker (~> 0.0.4)
15
+ ice_nine (~> 0.11.0)
16
+ thread_safe (~> 0.3, >= 0.3.1)
17
+ builder (3.2.4)
18
+ claide (1.0.3)
19
+ claide-plugins (0.9.2)
20
+ cork
21
+ nap
22
+ open4 (~> 1.3)
23
+ coderay (1.1.3)
24
+ coercible (1.0.0)
25
+ descendants_tracker (~> 0.0.1)
26
+ colored2 (3.1.2)
27
+ cork (0.3.0)
28
+ colored2 (~> 3.1)
29
+ danger (8.2.1)
30
+ claide (~> 1.0)
31
+ claide-plugins (>= 0.9.2)
32
+ colored2 (~> 3.1)
33
+ cork (~> 0.1)
34
+ faraday (>= 0.9.0, < 2.0)
35
+ faraday-http-cache (~> 2.0)
36
+ git (~> 1.7)
37
+ kramdown (~> 2.3)
38
+ kramdown-parser-gfm (~> 1.0)
39
+ no_proxy_fix
40
+ octokit (~> 4.7)
41
+ terminal-table (~> 1)
42
+ danger-commit_lint (0.0.7)
43
+ danger-plugin-api (~> 1.0)
44
+ danger-plugin-api (1.0.0)
45
+ danger (> 2.0)
46
+ descendants_tracker (0.0.4)
47
+ thread_safe (~> 0.3, >= 0.3.1)
48
+ docile (1.3.2)
49
+ equalizer (0.0.11)
50
+ erubis (2.7.0)
51
+ faraday (1.1.0)
52
+ multipart-post (>= 1.2, < 3)
53
+ ruby2_keywords
54
+ faraday-http-cache (2.2.0)
55
+ faraday (>= 0.8)
56
+ flay (2.12.1)
57
+ erubis (~> 2.7.0)
58
+ path_expander (~> 1.0)
59
+ ruby_parser (~> 3.0)
60
+ sexp_processor (~> 4.0)
61
+ flog (4.6.4)
62
+ path_expander (~> 1.0)
63
+ ruby_parser (~> 3.1, > 3.1.0)
64
+ sexp_processor (~> 4.8)
65
+ git (1.7.0)
66
+ rchardet (~> 1.8)
67
+ ice_nine (0.11.2)
68
+ kramdown (2.3.0)
69
+ rexml
70
+ kramdown-parser-gfm (1.1.0)
71
+ kramdown (~> 2.0)
72
+ kwalify (0.7.2)
73
+ launchy (2.5.0)
74
+ addressable (~> 2.7)
75
+ method_source (0.9.2)
9
76
  minitest (5.14.1)
77
+ minitest-focus (1.2.1)
78
+ minitest (>= 4, < 6)
79
+ minitest-reporters (1.4.2)
80
+ ansi
81
+ builder
82
+ minitest (>= 5.0)
83
+ ruby-progressbar
84
+ multipart-post (2.1.1)
85
+ nap (1.1.0)
86
+ no_proxy_fix (0.1.2)
87
+ octokit (4.19.0)
88
+ faraday (>= 0.9)
89
+ sawyer (~> 0.8.0, >= 0.5.3)
90
+ open4 (1.3.4)
91
+ parallel (1.19.2)
92
+ parser (2.7.1.3)
93
+ ast (~> 2.4.0)
94
+ path_expander (1.1.0)
95
+ pry (0.12.2)
96
+ coderay (~> 1.1.0)
97
+ method_source (~> 0.9.0)
98
+ pry-nav (0.3.0)
99
+ pry (>= 0.9.10, < 0.13.0)
100
+ psych (3.1.0)
101
+ public_suffix (4.0.5)
102
+ rainbow (3.0.0)
10
103
  rake (12.3.3)
104
+ rchardet (1.8.0)
105
+ reek (6.0.1)
106
+ kwalify (~> 0.7.0)
107
+ parser (>= 2.5.0.0, < 2.8, != 2.5.1.1)
108
+ psych (~> 3.1.0)
109
+ rainbow (>= 2.0, < 4.0)
110
+ regexp_parser (1.7.1)
111
+ rexml (3.2.4)
112
+ rubocop (0.85.1)
113
+ parallel (~> 1.10)
114
+ parser (>= 2.7.0.1)
115
+ rainbow (>= 2.2.2, < 4.0)
116
+ regexp_parser (>= 1.7)
117
+ rexml
118
+ rubocop-ast (>= 0.0.3)
119
+ ruby-progressbar (~> 1.7)
120
+ unicode-display_width (>= 1.4.0, < 2.0)
121
+ rubocop-ast (0.0.3)
122
+ parser (>= 2.7.0.1)
123
+ ruby-progressbar (1.10.1)
124
+ ruby2_keywords (0.0.2)
125
+ ruby_parser (3.14.2)
126
+ sexp_processor (~> 4.9)
127
+ rubycritic (4.5.0)
128
+ flay (~> 2.8)
129
+ flog (~> 4.4)
130
+ launchy (>= 2.0.0)
131
+ parser (>= 2.6.0)
132
+ rainbow (~> 3.0)
133
+ reek (~> 6.0, < 7.0)
134
+ ruby_parser (~> 3.8)
135
+ simplecov (>= 0.17.0)
136
+ tty-which (~> 0.4.0)
137
+ virtus (~> 1.0)
138
+ sawyer (0.8.2)
139
+ addressable (>= 2.3.5)
140
+ faraday (> 0.8, < 2.0)
141
+ sexp_processor (4.15.0)
142
+ simplecov (0.18.5)
143
+ docile (~> 1.1)
144
+ simplecov-html (~> 0.11)
145
+ simplecov-html (0.12.2)
146
+ terminal-table (1.8.0)
147
+ unicode-display_width (~> 1.1, >= 1.1.1)
148
+ thread_safe (0.3.6)
149
+ tty-which (0.4.2)
150
+ unicode-display_width (1.7.0)
151
+ virtus (1.0.5)
152
+ axiom-types (~> 0.1)
153
+ coercible (~> 1.0)
154
+ descendants_tracker (~> 0.0, >= 0.0.3)
155
+ equalizer (~> 0.0, >= 0.0.9)
11
156
 
12
157
  PLATFORMS
13
158
  ruby
14
159
 
15
160
  DEPENDENCIES
161
+ danger
162
+ danger-commit_lint
16
163
  minitest (~> 5.0)
164
+ minitest-focus
165
+ minitest-reporters
166
+ pry-nav
17
167
  rake (~> 12.0)
168
+ rubocop
169
+ rubycritic
170
+ simplecov
18
171
  uxid!
19
-
20
- BUNDLED WITH
21
- 2.1.4
File without changes
data/README.md CHANGED
@@ -1,15 +1,46 @@
1
1
  # UXID
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/uxid`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ ![MIT License][badge_license_url]
4
+ ![Gem Version][badge_version_url]
5
+
6
+
7
+ **U**ser e**X**perience focused **ID**entifiers (UXIDs) are identifiers which:
8
+
9
+ * Describe the resource (aid in debugging and investigation)
10
+ * Work well with copy and paste (double clicking selects the entire ID)
11
+ * Can be shortened for low cardinality resources
12
+ * Are secure against enumeration attacks
13
+ * Can be generated by application code (not tied to the datastore)
14
+ * Are K-sortable (lexicographically sortable by time - works well with datastore indexing)
15
+ * Do not require any coordination (human or automated) at startup, or generation
16
+ * Are very unlikely to collide (more likely with less randomness)
17
+ * Are easily and accurately transmitted to another human using a telephone
18
+
19
+ Many of the concepts of Stripe IDs have been used in this library.
20
+
21
+ ## Usage
22
+
23
+ #### Generating UXIDs
24
+
25
+ ```ruby
26
+ # No options generates a basic ULID
27
+ UXID.generate # "01EMDGJF0DQXQJ8FM78XE97Y3H"
28
+
29
+ # A prefix can be provided
30
+ UXID.generate prefix: "cus" # "cus_01EMDGJF0DQXQJ8FM78XE97Y3H"
31
+
32
+ # The amount of entropy can be decreased for smaller cardinality resources
33
+ # T-Shirt sizes can be used (:xs, :s, :m, :l, :xl) or (:xsmall, :small, :medium, :large, :xlarge)
34
+ UXID.generate prefix: "cus", size: :small # "cus_01EQRH884AQYY1"
35
+ ```
4
36
 
5
- TODO: Delete this and the text above, and describe your gem
6
37
 
7
38
  ## Installation
8
39
 
9
40
  Add this line to your application's Gemfile:
10
41
 
11
42
  ```ruby
12
- gem 'uxid'
43
+ gem "uxid"
13
44
  ```
14
45
 
15
46
  And then execute:
@@ -20,9 +51,6 @@ Or install it yourself as:
20
51
 
21
52
  $ gem install uxid
22
53
 
23
- ## Usage
24
-
25
- TODO: Write usage instructions here
26
54
 
27
55
  ## Development
28
56
 
@@ -38,3 +66,10 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/riddle
38
66
  ## License
39
67
 
40
68
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
69
+
70
+ <!-- LINKS -->
71
+ [mit_license_url]: http://opensource.org/licenses/MIT
72
+
73
+ <!-- BADGES -->
74
+ [badge_license_url]: https://img.shields.io/badge/license-MIT-brightgreen.svg?cacheSeconds=3600?style=flat-square
75
+ [badge_version_url]: https://badge.fury.io/rb/uxid.svg
data/Rakefile CHANGED
@@ -1,10 +1,3 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ Rake.add_rakelib "lib/tasks"
3
2
 
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
8
- end
9
-
10
- task :default => :test
3
+ task default: :test
@@ -3,12 +3,5 @@
3
3
  require "bundler/setup"
4
4
  require "uxid"
5
5
 
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
6
+ require "pry"
7
+ Pry.start
@@ -0,0 +1,4 @@
1
+ begin
2
+ require "bundler/gem_tasks"
3
+ rescue LoadError
4
+ end
@@ -0,0 +1,2 @@
1
+ desc "Runs tests, linting, audits, ..."
2
+ task check: %w[ test linting:dev metrics:quality ]
@@ -0,0 +1,19 @@
1
+ begin
2
+ require "rubocop/rake_task"
3
+
4
+ desc "Run Linting (RuboCop)"
5
+ task linting: "linting:dev"
6
+
7
+ namespace :linting do
8
+ common_options = %w[ --display-cop-names --extra-details --config=.rubocop.yml --parallel ]
9
+
10
+ RuboCop::RakeTask.new :dev do |t|
11
+ t.options = common_options
12
+ end
13
+
14
+ RuboCop::RakeTask.new :report do |t|
15
+ t.options = common_options + %w[ --format=html --out=reports/linting/index.html ]
16
+ end
17
+ end
18
+ rescue LoadError
19
+ end
@@ -0,0 +1,12 @@
1
+ begin
2
+ require "rubycritic/rake_task"
3
+
4
+ namespace :metrics do
5
+ RubyCritic::RakeTask.new do |task|
6
+ task.name = "quality"
7
+ task.paths = FileList["lib/**/*.rb"]
8
+ task.options = "--format html --no-browser --path reports/quality"
9
+ end
10
+ end
11
+ rescue LoadError
12
+ end
@@ -0,0 +1,8 @@
1
+ require "rake/testtask"
2
+
3
+ Rake::TestTask.new :test do |t|
4
+ t.libs << "lib"
5
+ t.libs << "test"
6
+ t.test_files = FileList["test/**/*_test.rb"]
7
+ t.warning = false
8
+ end
@@ -1,5 +1,68 @@
1
+ # frozen-string-literal: true
2
+
3
+ if RUBY_VERSION >= "2.5"
4
+ require "securerandom"
5
+ else
6
+ require "sysrandom/securerandom"
7
+ end
8
+
9
+ require "uxid/model"
10
+ require "uxid/encoder"
1
11
  require "uxid/version"
2
12
 
3
13
  module UXID
14
+ CROCKFORD_ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
15
+ DELIMITER = "_"
16
+
17
+ SIZE_WARNING_MESSAGE = <<-EOM
18
+ WARN: The UXID :size param is for Symbol T-Shirt sizes only.
19
+ Please use the :size param with Symbols (:xs, :s, :m, :l, :xl, or :xsmall, :small, :medium, :large, :xlarge),
20
+ or use the :rand_size param for specific size of random bytes.
21
+ EOM
22
+
4
23
  class Error < StandardError; end
24
+
25
+ def self.generate attrs = {}
26
+ model = new attrs
27
+ model.encode
28
+ end
29
+
30
+ def self.new attrs = {}
31
+ model = ::UXID::Model.new
32
+
33
+ model.time = attrs[:time] || Time.now
34
+ model.prefix = attrs[:prefix] || ""
35
+ model.size = attrs[:size]
36
+
37
+ if attrs[:rand_size]
38
+ model.rand_size = attrs[:rand_size]
39
+ else
40
+ case model.size
41
+ when Integer
42
+ puts SIZE_WARNING_MESSAGE
43
+ model.rand_size = model.size
44
+
45
+ when String
46
+ puts SIZE_WARNING_MESSAGE
47
+ model.rand_size = 10
48
+
49
+ when :xs, :xsmall
50
+ model.rand_size = 0
51
+
52
+ when :s, :small
53
+ model.rand_size = 2
54
+
55
+ when :m, :medium
56
+ model.rand_size = 5
57
+
58
+ when :l, :large
59
+ model.rand_size = 7
60
+
61
+ else
62
+ model.rand_size = 10
63
+ end
64
+ end
65
+
66
+ model
67
+ end
5
68
  end
@@ -0,0 +1,180 @@
1
+ module UXID
2
+ class Encoder
3
+ def self.encode model
4
+ new(model).encode
5
+ end
6
+
7
+ def initialize model
8
+ @model = model
9
+ end
10
+
11
+ def encode
12
+ @model.time_encoded = encode_time
13
+ @model.entropy_encoded = public_send "encode_entropy_#{@model.rand_size}"
14
+
15
+ @model.encoded
16
+ end
17
+
18
+ def encode_entropy_0; ""; end
19
+
20
+ def encode_entropy_1
21
+ b0, _b1 = @model.entropy_bytes
22
+
23
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
24
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2)]
25
+ end
26
+
27
+ def encode_entropy_2
28
+ b0, b1 = @model.entropy_bytes
29
+
30
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
31
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
32
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
33
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4)]
34
+ end
35
+
36
+ def encode_entropy_3
37
+ b0, b1, b2 = @model.entropy_bytes
38
+
39
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
40
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
41
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
42
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
43
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1)]
44
+ end
45
+
46
+ def encode_entropy_4
47
+ b0, b1, b2, b3 = @model.entropy_bytes
48
+
49
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
50
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
51
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
52
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
53
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1) | ((b3&128)>>7)] +
54
+ UXID::CROCKFORD_ENCODING[(b3&124)>>2] +
55
+ UXID::CROCKFORD_ENCODING[((b3&3)<<3)]
56
+ end
57
+
58
+ def encode_entropy_5
59
+ b0, b1, b2, b3, b4 = @model.entropy_bytes
60
+
61
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
62
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
63
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
64
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
65
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1) | ((b3&128)>>7)] +
66
+ UXID::CROCKFORD_ENCODING[(b3&124)>>2] +
67
+ UXID::CROCKFORD_ENCODING[((b3&3)<<3) | ((b4&224)>>5)] +
68
+ UXID::CROCKFORD_ENCODING[b4&31]
69
+ end
70
+
71
+ def encode_entropy_6
72
+ b0, b1, b2, b3, b4, b5 = @model.entropy_bytes
73
+
74
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
75
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
76
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
77
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
78
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1) | ((b3&128)>>7)] +
79
+ UXID::CROCKFORD_ENCODING[(b3&124)>>2] +
80
+ UXID::CROCKFORD_ENCODING[((b3&3)<<3) | ((b4&224)>>5)] +
81
+ UXID::CROCKFORD_ENCODING[b4&31] +
82
+ UXID::CROCKFORD_ENCODING[(b5&248)>>3] +
83
+ UXID::CROCKFORD_ENCODING[((b5&7)<<2)]
84
+ end
85
+
86
+ def encode_entropy_7
87
+ b0, b1, b2, b3, b4, b5, b6 = @model.entropy_bytes
88
+
89
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
90
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
91
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
92
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
93
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1) | ((b3&128)>>7)] +
94
+ UXID::CROCKFORD_ENCODING[(b3&124)>>2] +
95
+ UXID::CROCKFORD_ENCODING[((b3&3)<<3) | ((b4&224)>>5)] +
96
+ UXID::CROCKFORD_ENCODING[b4&31] +
97
+ UXID::CROCKFORD_ENCODING[(b5&248)>>3] +
98
+ UXID::CROCKFORD_ENCODING[((b5&7)<<2) | ((b6&192)>>6)] +
99
+ UXID::CROCKFORD_ENCODING[(b6&62)>>1] +
100
+ UXID::CROCKFORD_ENCODING[((b6&1)<<4)]
101
+ end
102
+
103
+ def encode_entropy_8
104
+ b0, b1, b2, b3, b4, b5, b6, b7 = @model.entropy_bytes
105
+
106
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
107
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
108
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
109
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
110
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1) | ((b3&128)>>7)] +
111
+ UXID::CROCKFORD_ENCODING[(b3&124)>>2] +
112
+ UXID::CROCKFORD_ENCODING[((b3&3)<<3) | ((b4&224)>>5)] +
113
+ UXID::CROCKFORD_ENCODING[b4&31] +
114
+ UXID::CROCKFORD_ENCODING[(b5&248)>>3] +
115
+ UXID::CROCKFORD_ENCODING[((b5&7)<<2) | ((b6&192)>>6)] +
116
+ UXID::CROCKFORD_ENCODING[(b6&62)>>1] +
117
+ UXID::CROCKFORD_ENCODING[((b6&1)<<4) | ((b7&240)>>4)] +
118
+ UXID::CROCKFORD_ENCODING[((b7&15)<<1)]
119
+ end
120
+
121
+ def encode_entropy_9
122
+ b0, b1, b2, b3, b4, b5, b6, b7, b8 = @model.entropy_bytes
123
+
124
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
125
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
126
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
127
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
128
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1) | ((b3&128)>>7)] +
129
+ UXID::CROCKFORD_ENCODING[(b3&124)>>2] +
130
+ UXID::CROCKFORD_ENCODING[((b3&3)<<3) | ((b4&224)>>5)] +
131
+ UXID::CROCKFORD_ENCODING[b4&31] +
132
+ UXID::CROCKFORD_ENCODING[(b5&248)>>3] +
133
+ UXID::CROCKFORD_ENCODING[((b5&7)<<2) | ((b6&192)>>6)] +
134
+ UXID::CROCKFORD_ENCODING[(b6&62)>>1] +
135
+ UXID::CROCKFORD_ENCODING[((b6&1)<<4) | ((b7&240)>>4)] +
136
+ UXID::CROCKFORD_ENCODING[((b7&15)<<1) | ((b8&128)>>7)] +
137
+ UXID::CROCKFORD_ENCODING[(b8&124)>>2] +
138
+ UXID::CROCKFORD_ENCODING[((b8&3)<<3)]
139
+ end
140
+
141
+ def encode_entropy_10
142
+ b0, b1, b2, b3, b4, b5, b6, b7, b8, b9 = @model.entropy_bytes
143
+
144
+ UXID::CROCKFORD_ENCODING[(b0&248)>>3] +
145
+ UXID::CROCKFORD_ENCODING[((b0&7)<<2) | ((b1&192)>>6)] +
146
+ UXID::CROCKFORD_ENCODING[(b1&62)>>1] +
147
+ UXID::CROCKFORD_ENCODING[((b1&1)<<4) | ((b2&240)>>4)] +
148
+ UXID::CROCKFORD_ENCODING[((b2&15)<<1) | ((b3&128)>>7)] +
149
+ UXID::CROCKFORD_ENCODING[(b3&124)>>2] +
150
+ UXID::CROCKFORD_ENCODING[((b3&3)<<3) | ((b4&224)>>5)] +
151
+ UXID::CROCKFORD_ENCODING[b4&31] +
152
+ UXID::CROCKFORD_ENCODING[(b5&248)>>3] +
153
+ UXID::CROCKFORD_ENCODING[((b5&7)<<2) | ((b6&192)>>6)] +
154
+ UXID::CROCKFORD_ENCODING[(b6&62)>>1] +
155
+ UXID::CROCKFORD_ENCODING[((b6&1)<<4) | ((b7&240)>>4)] +
156
+ UXID::CROCKFORD_ENCODING[((b7&15)<<1) | ((b8&128)>>7)] +
157
+ UXID::CROCKFORD_ENCODING[(b8&124)>>2] +
158
+ UXID::CROCKFORD_ENCODING[((b8&3)<<3) | ((b9&224)>>5)] +
159
+ UXID::CROCKFORD_ENCODING[b9&31]
160
+ end
161
+
162
+ def encode_time
163
+ # Get the 5 bytes of the 48bit time
164
+ b0, b1, b2, b3, b4, b5 = @model.time_bytes
165
+
166
+ # Split these 5 bytes up into 10 characters using the encoding
167
+ # and join them together as a string
168
+ UXID::CROCKFORD_ENCODING[(b0&224)>>5] +
169
+ UXID::CROCKFORD_ENCODING[b0&31] +
170
+ UXID::CROCKFORD_ENCODING[(b1&248)>>3] +
171
+ UXID::CROCKFORD_ENCODING[((b1&7)<<2) | ((b2&192)>>6)] +
172
+ UXID::CROCKFORD_ENCODING[(b2&62)>>1] +
173
+ UXID::CROCKFORD_ENCODING[((b2&1)<<4) | ((b3&240)>>4)] +
174
+ UXID::CROCKFORD_ENCODING[((b3&15)<<1) | ((b4&128)>>7)] +
175
+ UXID::CROCKFORD_ENCODING[(b4&124)>>2] +
176
+ UXID::CROCKFORD_ENCODING[((b4&3)<<3) | ((b5&224)>>5)] +
177
+ UXID::CROCKFORD_ENCODING[b5&31]
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,44 @@
1
+ require "uxid/encoder"
2
+
3
+ module UXID
4
+ class Model
5
+ attr_accessor :time, :time_encoded, :entropy, :entropy_encoded, :prefix, :size, :rand_size
6
+
7
+ def encode
8
+ encoder = ::UXID::Encoder.new self
9
+ encoder.encode
10
+ end
11
+
12
+ # Returns time as 48 bits
13
+ def time_bytes
14
+ return @time_bytes if @time_bytes
15
+
16
+ time_ms = (@time.to_f * 1000).to_i
17
+ bytes = [time_ms].pack "Q>"
18
+ bytes_string = bytes[2..-1]
19
+ @time_bytes = bytes_string.bytes
20
+ end
21
+
22
+ def entropy_bytes
23
+ return @entropy_bytes if @entropy_bytes
24
+
25
+ bytes_string = SecureRandom.random_bytes @rand_size
26
+ @entropy_bytes = bytes_string.bytes
27
+ return @entropy_bytes
28
+ end
29
+
30
+ def encoded
31
+ id = time_encoded + entropy_encoded
32
+
33
+ if has_prefix?
34
+ [prefix, id].join UXID::DELIMITER
35
+ else
36
+ id
37
+ end
38
+ end
39
+
40
+ def has_prefix?
41
+ !(prefix.nil? || prefix == "")
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module UXID
2
- VERSION = "0.0.1"
2
+ VERSION = "0.2.3"
3
3
  end
@@ -1,4 +1,5 @@
1
- require_relative 'lib/uxid/version'
1
+ require_relative "lib/uxid/version"
2
+ here = File.expand_path "..", __FILE__
2
3
 
3
4
  Gem::Specification.new do |spec|
4
5
  spec.name = "uxid"
@@ -6,21 +7,21 @@ Gem::Specification.new do |spec|
6
7
  spec.authors = ["JohnnyT"]
7
8
  spec.email = ["ubergeek3141@gmail.com"]
8
9
 
9
- spec.summary = "User eXperience focused IDentifiers"
10
+ spec.summary = "Generates IDs like: cus_01EPEY1JMK and txn_01EPEY2P06TR1RTV07 (similar to Stripe identifiers)."
10
11
  spec.description = spec.summary
11
- spec.homepage = "https://github.com/riddler/uxid"
12
+ spec.homepage = "https://github.com/riddler/uxid-rb"
12
13
  spec.license = "MIT"
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+ spec.required_ruby_version = Gem::Requirement.new ">= 2.3.0"
14
15
 
15
16
  spec.metadata["homepage_uri"] = spec.homepage
16
17
  spec.metadata["source_code_uri"] = spec.homepage
17
18
 
18
19
  # Specify which files should be added to the gem when it is released.
19
20
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
21
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ spec.files = Dir.chdir here do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match %r{^(test|spec|features)/} }
22
23
  end
23
24
  spec.bindir = "exe"
24
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename f }
25
26
  spec.require_paths = ["lib"]
26
27
  end
metadata CHANGED
@@ -1,40 +1,53 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uxid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - JohnnyT
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-18 00:00:00.000000000 Z
11
+ date: 2020-11-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: User eXperience focused IDentifiers
13
+ description: 'Generates IDs like: cus_01EPEY1JMK and txn_01EPEY2P06TR1RTV07 (similar
14
+ to Stripe identifiers).'
14
15
  email:
15
16
  - ubergeek3141@gmail.com
16
17
  executables: []
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
21
+ - ".github/workflows/build.yml"
22
+ - ".gitignore"
23
+ - ".rubocop.yml"
24
+ - ".simplecov"
20
25
  - CHANGELOG.md
26
+ - Dangerfile
21
27
  - Gemfile
22
28
  - Gemfile.lock
23
- - LICENSE.txt
29
+ - LICENSE
24
30
  - README.md
25
31
  - Rakefile
26
32
  - bin/console
27
33
  - bin/setup
34
+ - lib/tasks/bundler.rake
35
+ - lib/tasks/check.rake
36
+ - lib/tasks/linting.rake
37
+ - lib/tasks/quality.rake
38
+ - lib/tasks/test.rake
28
39
  - lib/uxid.rb
40
+ - lib/uxid/encoder.rb
41
+ - lib/uxid/model.rb
29
42
  - lib/uxid/version.rb
30
43
  - uxid.gemspec
31
- homepage: https://github.com/riddler/uxid
44
+ homepage: https://github.com/riddler/uxid-rb
32
45
  licenses:
33
46
  - MIT
34
47
  metadata:
35
- homepage_uri: https://github.com/riddler/uxid
36
- source_code_uri: https://github.com/riddler/uxid
37
- post_install_message:
48
+ homepage_uri: https://github.com/riddler/uxid-rb
49
+ source_code_uri: https://github.com/riddler/uxid-rb
50
+ post_install_message:
38
51
  rdoc_options: []
39
52
  require_paths:
40
53
  - lib
@@ -49,8 +62,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
49
62
  - !ruby/object:Gem::Version
50
63
  version: '0'
51
64
  requirements: []
52
- rubygems_version: 3.1.2
53
- signing_key:
65
+ rubygems_version: 3.1.4
66
+ signing_key:
54
67
  specification_version: 4
55
- summary: User eXperience focused IDentifiers
68
+ summary: 'Generates IDs like: cus_01EPEY1JMK and txn_01EPEY2P06TR1RTV07 (similar to
69
+ Stripe identifiers).'
56
70
  test_files: []