uxid 0.0.1 → 0.2.3

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 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: []