lite-uxid 2.0.1 → 2.0.2

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: 9078e4e13dc6877ed30a6a0028ad4327ff95d3056a5303f789137272e2bb0f12
4
- data.tar.gz: c25e8acbb22ad4e4381bf9b07018eaf12daaf8e1d0123cee24f5fa9c8af8e87a
3
+ metadata.gz: 7a5ffc2eb4b3088dfba64e17944b8da4e50b6daf1340e45dafb6ad9c98917bad
4
+ data.tar.gz: da4d9ac855493ca6556782375e775192e07ef4ecd8a8a90b7ed13a76160d6cd9
5
5
  SHA512:
6
- metadata.gz: bd5d7ef2cd4c425fb798dea874a7f395e20e5514ca07fb807d673feb75187e8a236236bd7f833084983a820d71a05a7a27c80d72138a13f888fb5b088a4c869f
7
- data.tar.gz: 24462c53958076c1435e1012f3608002d23fdb01b3d59d00ac9d7d78c81f8f1d91b3a80fcac78d9a6a9ce358d9db728af6dd6df3d6815037a1c7dfa25515ba3f
6
+ metadata.gz: 94dd97afca7b4eaebb652c6f916211b605a002645eae9500e0cc2fac1f85b1b213447e3f67278e768150acaf82dde5a7a1360cf86fe5142cb365e5d480404422
7
+ data.tar.gz: b15bb1df870cf94356098e8c87542f44e034a64dced29ddc0d7ebe292d9ceeaeb457a956bab23b8f8fee40e1d3c4c40e605805386f78e4807bd15af809b9f1da
data/CHANGELOG.md CHANGED
@@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.0.2] - 2024-09-23
10
+ ### Added
11
+ - Prefixes to uuid and ulid
12
+ ### Changed
13
+ - Improve configuration template
14
+ - Improve hashid generation
15
+ - Improve specs
16
+ - Improve docs
17
+ ### Removed
18
+ - Hashid size option
19
+
9
20
  ## [2.0.1] - 2024-09-23
10
21
  ### Changed
11
22
  - Renamed `Scatterid` to `Obfuscateid`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lite-uxid (2.0.1)
4
+ lite-uxid (2.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -162,7 +162,7 @@ GEM
162
162
  concurrent-ruby (~> 1.0)
163
163
  unicode-display_width (2.6.0)
164
164
  useragent (0.16.10)
165
- webrick (1.8.1)
165
+ webrick (1.8.2)
166
166
  zeitwerk (2.6.18)
167
167
 
168
168
  PLATFORMS
data/README.md CHANGED
@@ -27,12 +27,14 @@ Or install it yourself as:
27
27
 
28
28
  * [Configuration](#configuration)
29
29
  * [Usage](#usage)
30
- * [HashID](#hashid)
31
- * [NanoID](#nanoid)
32
- * [ObfuscateID](#obfuscateid)
33
- * [ULID](#ulid)
34
- * [UUID](#uuid)
35
30
  * [Options](#options)
31
+ * [Reversible](#reversible)
32
+ * [HashID](#hashid)
33
+ * [ObfuscateID](#obfuscateid)
34
+ * [Irreversible](#Irreversible)
35
+ * [NanoID](#nanoid)
36
+ * [ULID](#ulid)
37
+ * [UUID](#uuid)
36
38
  * [ActiveRecord](#active_record)
37
39
  * [Benchmarks](#benchmarks)
38
40
 
@@ -42,101 +44,112 @@ Or install it yourself as:
42
44
  `config/initalizers/lite_uxid.rb`
43
45
 
44
46
  ```ruby
45
- Lite::Uxid::ALPHANUMERIC = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
46
- Lite::Uxid::COCKFORDS_32 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
47
- Lite::Uxid::WEB_SAFE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"
48
-
49
47
  Lite::Uxid.configure do |config|
50
- config.hashid_charset = ALPHANUMERIC
48
+ # HashID
49
+ config.hashid_charset = Lite::Uxid::ALPHANUMERIC
51
50
  config.hashid_salt = 1_369_136
52
- config.hashid_size = 16
53
- config.nanoid_charset = WEB_SAFE
51
+
52
+ # NanoID
53
+ config.nanoid_charset = Lite::Uxid::WEB_SAFE
54
54
  config.nanoid_size = 21
55
- config.ulid_charset = COCKFORDS_32
55
+
56
+ # ObfuscatedID
57
+ config.obfuscateid_spin = 0
58
+
59
+ # ULID
60
+ config.ulid_charset = Lite::Uxid::COCKFORDS_32
56
61
  config.ulid_size = 26
62
+
63
+ # UUID
57
64
  config.uuid_version = 4
58
65
  end
59
66
  ```
60
67
 
61
68
  ## Usage
62
69
 
63
- #### Instance
70
+ ### Instance call
71
+
64
72
  ```ruby
65
73
  coder = Lite::Uxid::Reversible::Hashid.new(10, size: 12)
66
74
  coder.encode #=> '67wGI0'
67
75
  ```
68
76
 
69
- #### Class
77
+ ### Class call
70
78
  ```ruby
71
79
  Lite::Uxid::Reversible::Hashid.decode('67wGI0', size: 12) #=> 10
72
80
  ```
73
81
 
74
- ## HashID
82
+ ## Options
75
83
 
76
- [More information](https://hashids.org)
84
+ Local options can be passed to override global options.
77
85
 
78
86
  ```ruby
79
- Lite::Uxid::Reversible::Hashid.encode(10) #=> '1zWr1m0'
80
- Lite::Uxid::Reversible::Hashid.decode('1zWr1m0') #=> 10
87
+ Lite::Uxid::Irreversible::Ulid.encode(charset: 'abc123', size: 12) #=> 'a3b12c12c3ca'
81
88
  ```
82
89
 
83
- ## NanoID
84
-
85
- [More information](https://github.com/ai/nanoid)
90
+ Passable options are:
86
91
 
87
92
  ```ruby
88
- Lite::Uxid::Irreversible::Nanoid.encode #=> 'sMuNUa3Cegn6r5GRQ4Ij2'
93
+ {
94
+ charset: 'string', # Available for: hashid, nanoid, ulid
95
+ salt: 'string', # Available for: hashid
96
+ size: 'integer', # Available for: nanoid, ulid
97
+ spin: 'integer', # Available for: obfuscateid
98
+ version: 'integer', # Available for: uuid
99
+ prefix: 'string' # Available for: hashid, nanoid, ulid, uuid
100
+ }
89
101
  ```
90
102
 
91
- ## ObfuscateID
103
+ ## Reversible
92
104
 
93
- [More information](https://github.com/namick/scatter_swap)
105
+ ### HashID
106
+
107
+ - [More information](https://hashids.org)
94
108
 
95
109
  ```ruby
96
- Lite::Uxid::Reversible::Obfuscateid.encode(10) #=> '2056964183'
97
- Lite::Uxid::Reversible::Obfuscateid.decode(2056964183) #=> 10
110
+ Lite::Uxid::Reversible::Hashid.encode(10) #=> '7pau2oXSklq0'
111
+ Lite::Uxid::Reversible::Hashid.decode('7pau2oXSklq0') #=> 10
98
112
  ```
99
113
 
100
- ## ULID
114
+ ### NanoID
101
115
 
102
- [More information](https://github.com/ulid/spec)
116
+ - [More information](https://github.com/ai/nanoid)
103
117
 
104
118
  ```ruby
105
- Lite::Uxid::Irreversible::Ulid.encode #=> '01GJAY9KGR539EZF4QWYEJGSN7'
119
+ Lite::Uxid::Irreversible::Nanoid.encode #=> 'sMuNUa3Cegn6r5GRQ4Ij2'
106
120
  ```
107
121
 
108
- ## UUID
122
+ ## Irreversible
123
+
124
+ ### ObfuscateID
109
125
 
110
- Implements `v4` and `v7` of the specification. [More information](https://en.wikipedia.org/wiki/Universally_unique_identifier)
126
+ - [More information](https://github.com/namick/scatter_swap)
111
127
 
112
128
  ```ruby
113
- Lite::Uxid::Irreversible::Uuid.encode #=> '4376a67e-1189-44b3-a599-7f7566bf105b'
129
+ Lite::Uxid::Reversible::Obfuscateid.encode(10) #=> 2056964183
130
+ Lite::Uxid::Reversible::Obfuscateid.decode(2056964183) #=> 10
114
131
  ```
115
132
 
116
- ## Options
133
+ ### ULID
117
134
 
118
- Local options can be passed to override global options.
135
+ - [More information](https://github.com/ulid/spec)
119
136
 
120
137
  ```ruby
121
- Lite::Uxid::Irreversible::Ulid.encode(charset: 'abc123', size: 12) #=> 'a3b12c12c3ca'
138
+ Lite::Uxid::Irreversible::Ulid.encode #=> '01GJAY9KGR539EZF4QWYEJGSN7'
122
139
  ```
123
140
 
124
- Passable options are:
141
+ ### UUID
142
+
143
+ Implements `v4` and `v7` of the specification.
144
+ - [More information](https://en.wikipedia.org/wiki/Universally_unique_identifier)
125
145
 
126
146
  ```ruby
127
- {
128
- charset: 'string', # Available for: hashid, nanoid, ulid
129
- salt: 'string', # Available for: hashid
130
- size: 'integer', # Available for: hashid, nanoid, ulid
131
- spin: 'integer', # Available for: obfuscateid
132
- version: 'integer', # Available for: uuid
133
- prefix: 'string' # Available for: hashid, nanoid
134
- }
147
+ Lite::Uxid::Irreversible::Uuid.encode #=> '4376a67e-1189-44b3-a599-7f7566bf105b'
135
148
  ```
136
149
 
137
150
  ## ActiveRecord
138
151
 
139
- **Table**
152
+ ### Table
140
153
 
141
154
  Add the following attribute to all corresponding tables.
142
155
 
@@ -146,7 +159,7 @@ Add the following attribute to all corresponding tables.
146
159
  t.string :uxid, null: false, index: { unique: true }
147
160
  ```
148
161
 
149
- If using UUID and your database supports it:
162
+ If using UUID or ULID and your database supports it:
150
163
 
151
164
  ```ruby
152
165
  t.uuid :uxid, null: false, index: { unique: true }
@@ -156,7 +169,7 @@ t.uuid :uxid, null: false, index: { unique: true }
156
169
 
157
170
  `uxid` attribute will be automatically generated and applied when the record is created.
158
171
 
159
- #### HashID
172
+ ### Mixin
160
173
  ```ruby
161
174
  class User < ActiveRecord::Base
162
175
  # Pick one:
@@ -168,7 +181,7 @@ class User < ActiveRecord::Base
168
181
  end
169
182
  ```
170
183
 
171
- Add a prefix to `hashid` and `nanoid` record types by adding a `uxid_prefix` method.
184
+ HashID, NanoID, ULID, and UUID modules allow prefixing via the `uxid_prefix` method.
172
185
 
173
186
  ```ruby
174
187
  class User < ActiveRecord::Base
@@ -180,26 +193,38 @@ class User < ActiveRecord::Base
180
193
  end
181
194
  ```
182
195
 
183
- **Usage**
184
-
185
196
  Using the `hashid` and `nanoid` above provide handy methods to find records by uxid.
186
197
 
187
- #### Hashing methods
188
198
  ```ruby
189
199
  user = User.new
190
200
  user.id_to_uxid #=> Encodes the records id to uxid
191
201
  user.uxid_to_id #=> Decodes the records uxid to id
192
- ```
193
202
 
194
- #### Finder methods
195
- ```ruby
196
203
  User.find_by_uxid('x123') #=> Find record by uxid
197
204
  User.find_by_uxid!('x123') #=> Raises an ActiveRecord::RecordNotFound error if not found
198
205
  ```
199
206
 
200
207
  ## Benchmarks
201
208
 
202
- The classes ranked from fastest to slowest are `UUID`, `HashID`, `NanoID`, `ULID`, and `ObfuscateID`.
209
+ The classes ranked from fastest to slowest are `UUID`, `HashID`, `NanoID`, `ULID`, and `ObfuscateID`. Here are the latest results:
210
+
211
+ ```
212
+ Calculating -------------------------------------
213
+ Hashid 135.993k (± 2.9%) i/s (7.35 μs/i) - 681.588k in 5.016413s
214
+ Obfuscateid 30.702k (± 2.2%) i/s (32.57 μs/i) - 155.907k in 5.080592s
215
+ NanoID 99.327k (± 1.5%) i/s (10.07 μs/i) - 504.135k in 5.076630s
216
+ ULID 82.211k (± 2.3%) i/s (12.16 μs/i) - 418.455k in 5.092823s
217
+ UUID v4 237.629k (± 6.8%) i/s (4.21 μs/i) - 1.190M in 5.040477s
218
+ UUID v7 234.956k (±13.8%) i/s (4.26 μs/i) - 1.153M in 5.051057s
219
+
220
+ Comparison:
221
+ UUID v4: 237629.0 i/s
222
+ UUID v7: 234955.9 i/s - same-ish: difference falls within error
223
+ Hashid: 135993.5 i/s - 1.75x slower
224
+ NanoID: 99327.3 i/s - 2.39x slower
225
+ ULID: 82210.7 i/s - 2.89x slower
226
+ Obfuscateid: 30702.0 i/s - 7.74x slower
227
+ ```
203
228
 
204
229
  View how each compares by running the [benchmarks](https://github.com/drexed/lite-uxid/tree/master/benchmarks).
205
230
 
@@ -6,12 +6,12 @@ require "benchmark/ips"
6
6
  require "lite/uxid"
7
7
 
8
8
  Benchmark.ips do |x|
9
- x.report("Hashid") do
9
+ x.report("HashID") do
10
10
  id = rand(1..1_000_000)
11
11
  Lite::Uxid::Reversible::Hashid.encode(id)
12
12
  end
13
13
 
14
- x.report("Obfuscateid") do
14
+ x.report("ObfuscateID") do
15
15
  id = rand(1..1_000_000)
16
16
  Lite::Uxid::Reversible::Obfuscateid.encode(id)
17
17
  end
@@ -29,10 +29,15 @@ Benchmark.ips do |x|
29
29
  Lite::Uxid::Irreversible::Ulid.encode
30
30
  end
31
31
 
32
- x.report("UUID") do
32
+ x.report("UUID v4") do
33
33
  _id = rand(1..1_000_000)
34
34
  Lite::Uxid::Irreversible::Uuid.encode
35
35
  end
36
36
 
37
+ x.report("UUID v7") do
38
+ _id = rand(1..1_000_000)
39
+ Lite::Uxid::Irreversible::Uuid.encode(version: 7)
40
+ end
41
+
37
42
  x.compare!
38
43
  end
@@ -1,13 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Lite::Uxid.configure do |config|
4
- config.hashid_charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
5
- config.hashid_salt = 1_369_136
6
- config.hashid_size = 16
7
- config.nanoid_charset = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
8
- config.nanoid_size = 21
9
- config.obfuscateid_spin = 0
10
- config.ulid_charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
11
- config.ulid_size = 26
12
- config.uuid_version = 4
4
+ # HashID
5
+ # config.hashid_charset = Lite::Uxid::ALPHANUMERIC
6
+ # config.hashid_salt = 1_369_136
7
+
8
+ # NanoID
9
+ # config.nanoid_charset = Lite::Uxid::WEB_SAFE
10
+ # config.nanoid_size = 21
11
+
12
+ # ObfuscatedID
13
+ # config.obfuscateid_spin = 0
14
+
15
+ # ULID
16
+ # config.ulid_charset = Lite::Uxid::COCKFORDS_32
17
+ # config.ulid_size = 26
18
+
19
+ # UUID
20
+ # config.uuid_version = 4
13
21
  end
@@ -30,7 +30,7 @@ module Lite
30
30
  end
31
31
 
32
32
  def coder_length
33
- @coder_length ||= coder_charset.size
33
+ @coder_length ||= coder_charset.length
34
34
  end
35
35
 
36
36
  def coder_prefix
@@ -9,7 +9,7 @@ module Lite
9
9
 
10
10
  class Configuration
11
11
 
12
- attr_accessor :hashid_charset, :hashid_size, :hashid_salt,
12
+ attr_accessor :hashid_charset, :hashid_salt,
13
13
  :nanoid_charset, :nanoid_size,
14
14
  :obfuscateid_spin,
15
15
  :ulid_charset, :ulid_size,
@@ -18,7 +18,6 @@ module Lite
18
18
  def initialize
19
19
  @hashid_charset = ALPHANUMERIC
20
20
  @hashid_salt = 1_369_136
21
- @hashid_size = 16
22
21
  @nanoid_charset = WEB_SAFE
23
22
  @nanoid_size = 21
24
23
  @obfuscateid_spin = 0
@@ -18,7 +18,7 @@ module Lite
18
18
  pos -= 1
19
19
  end
20
20
 
21
- encoded_id
21
+ "#{coder_prefix}#{encoded_id}"
22
22
  end
23
23
 
24
24
  private
@@ -6,12 +6,15 @@ module Lite
6
6
  class Uuid < Base
7
7
 
8
8
  def encode
9
- case coder_version
10
- when 7
11
- SecureRandom.uuid_v7
12
- else
13
- SecureRandom.uuid
14
- end
9
+ encoded_id =
10
+ case coder_version
11
+ when 7
12
+ SecureRandom.uuid_v7
13
+ else
14
+ SecureRandom.uuid
15
+ end
16
+
17
+ "#{coder_prefix}#{encoded_id}"
15
18
  end
16
19
 
17
20
  end
@@ -43,7 +43,8 @@ module Lite
43
43
  end
44
44
 
45
45
  def uxid_prefix
46
- nil
46
+ # Define in your class to enable prefixing uxid.
47
+ # eg: "sub_" or "user_"
47
48
  end
48
49
 
49
50
  private
@@ -13,7 +13,8 @@ module Lite
13
13
  end
14
14
 
15
15
  def uxid_prefix
16
- nil
16
+ # Define in your class to enable prefixing uxid.
17
+ # eg: "sub_" or "user_"
17
18
  end
18
19
 
19
20
  private
@@ -12,10 +12,15 @@ module Lite
12
12
  end
13
13
  end
14
14
 
15
+ def uxid_prefix
16
+ # Define in your class to enable prefixing uxid.
17
+ # eg: "sub_" or "user_"
18
+ end
19
+
15
20
  private
16
21
 
17
22
  def callback_generate_uxid!
18
- self.uxid = Lite::Uxid::Irreversible::Ulid.encode
23
+ self.uxid = Lite::Uxid::Irreversible::Ulid.encode(prefix: uxid_prefix)
19
24
  end
20
25
 
21
26
  end
@@ -12,10 +12,15 @@ module Lite
12
12
  end
13
13
  end
14
14
 
15
+ def uxid_prefix
16
+ # Define in your class to enable prefixing uxid.
17
+ # eg: "sub_" or "user_"
18
+ end
19
+
15
20
  private
16
21
 
17
22
  def callback_generate_uxid!
18
- self.uxid = Lite::Uxid::Irreversible::Uuid.encode
23
+ self.uxid = Lite::Uxid::Irreversible::Uuid.encode(prefix: uxid_prefix)
19
24
  end
20
25
 
21
26
  end
@@ -5,14 +5,16 @@ module Lite
5
5
  module Reversible
6
6
  class Hashid < Base
7
7
 
8
+ MASK = 48
9
+
8
10
  def encode
9
- encoded_id = encode_chars((id + coder_salt) << coder_size)
11
+ encoded_id = encode_chars((id + coder_salt) << MASK)
10
12
  "#{coder_prefix}#{encoded_id}"
11
13
  end
12
14
 
13
15
  def decode
14
16
  encoded_id = id.delete_prefix(coder_prefix.to_s)
15
- (decode_chars(encoded_id) >> coder_size) - coder_salt
17
+ (decode_chars(encoded_id) >> MASK) - coder_salt
16
18
  end
17
19
 
18
20
  private
@@ -34,7 +36,7 @@ module Lite
34
36
  def decode_chars(encoded_id)
35
37
  pos = 0
36
38
  num = 0
37
- len = encoded_id.size
39
+ len = encoded_id.length
38
40
  max = len - 1
39
41
 
40
42
  while pos < len
@@ -3,7 +3,7 @@
3
3
  module Lite
4
4
  module Uxid
5
5
 
6
- VERSION = "2.0.1"
6
+ VERSION = "2.0.2"
7
7
 
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lite-uxid
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Gomez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-23 00:00:00.000000000 Z
11
+ date: 2024-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord