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 +4 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +2 -2
- data/README.md +81 -56
- data/benchmarks/compare.rb +8 -3
- data/lib/generators/lite/uxid/templates/install.rb +17 -9
- data/lib/lite/uxid/base.rb +1 -1
- data/lib/lite/uxid/configuration.rb +1 -2
- data/lib/lite/uxid/irreversible/ulid.rb +1 -1
- data/lib/lite/uxid/irreversible/uuid.rb +9 -6
- data/lib/lite/uxid/record/hashid.rb +2 -1
- data/lib/lite/uxid/record/nanoid.rb +2 -1
- data/lib/lite/uxid/record/ulid.rb +6 -1
- data/lib/lite/uxid/record/uuid.rb +6 -1
- data/lib/lite/uxid/reversible/hashid.rb +5 -3
- data/lib/lite/uxid/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a5ffc2eb4b3088dfba64e17944b8da4e50b6daf1340e45dafb6ad9c98917bad
|
4
|
+
data.tar.gz: da4d9ac855493ca6556782375e775192e07ef4ecd8a8a90b7ed13a76160d6cd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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
|
-
|
48
|
+
# HashID
|
49
|
+
config.hashid_charset = Lite::Uxid::ALPHANUMERIC
|
51
50
|
config.hashid_salt = 1_369_136
|
52
|
-
|
53
|
-
|
51
|
+
|
52
|
+
# NanoID
|
53
|
+
config.nanoid_charset = Lite::Uxid::WEB_SAFE
|
54
54
|
config.nanoid_size = 21
|
55
|
-
|
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
|
-
|
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
|
-
|
77
|
+
### Class call
|
70
78
|
```ruby
|
71
79
|
Lite::Uxid::Reversible::Hashid.decode('67wGI0', size: 12) #=> 10
|
72
80
|
```
|
73
81
|
|
74
|
-
##
|
82
|
+
## Options
|
75
83
|
|
76
|
-
|
84
|
+
Local options can be passed to override global options.
|
77
85
|
|
78
86
|
```ruby
|
79
|
-
Lite::Uxid::
|
80
|
-
Lite::Uxid::Reversible::Hashid.decode('1zWr1m0') #=> 10
|
87
|
+
Lite::Uxid::Irreversible::Ulid.encode(charset: 'abc123', size: 12) #=> 'a3b12c12c3ca'
|
81
88
|
```
|
82
89
|
|
83
|
-
|
84
|
-
|
85
|
-
[More information](https://github.com/ai/nanoid)
|
90
|
+
Passable options are:
|
86
91
|
|
87
92
|
```ruby
|
88
|
-
|
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
|
-
##
|
103
|
+
## Reversible
|
92
104
|
|
93
|
-
|
105
|
+
### HashID
|
106
|
+
|
107
|
+
- [More information](https://hashids.org)
|
94
108
|
|
95
109
|
```ruby
|
96
|
-
Lite::Uxid::Reversible::
|
97
|
-
Lite::Uxid::Reversible::
|
110
|
+
Lite::Uxid::Reversible::Hashid.encode(10) #=> '7pau2oXSklq0'
|
111
|
+
Lite::Uxid::Reversible::Hashid.decode('7pau2oXSklq0') #=> 10
|
98
112
|
```
|
99
113
|
|
100
|
-
|
114
|
+
### NanoID
|
101
115
|
|
102
|
-
[More information](https://github.com/
|
116
|
+
- [More information](https://github.com/ai/nanoid)
|
103
117
|
|
104
118
|
```ruby
|
105
|
-
Lite::Uxid::Irreversible::
|
119
|
+
Lite::Uxid::Irreversible::Nanoid.encode #=> 'sMuNUa3Cegn6r5GRQ4Ij2'
|
106
120
|
```
|
107
121
|
|
108
|
-
##
|
122
|
+
## Irreversible
|
123
|
+
|
124
|
+
### ObfuscateID
|
109
125
|
|
110
|
-
|
126
|
+
- [More information](https://github.com/namick/scatter_swap)
|
111
127
|
|
112
128
|
```ruby
|
113
|
-
Lite::Uxid::
|
129
|
+
Lite::Uxid::Reversible::Obfuscateid.encode(10) #=> 2056964183
|
130
|
+
Lite::Uxid::Reversible::Obfuscateid.decode(2056964183) #=> 10
|
114
131
|
```
|
115
132
|
|
116
|
-
|
133
|
+
### ULID
|
117
134
|
|
118
|
-
|
135
|
+
- [More information](https://github.com/ulid/spec)
|
119
136
|
|
120
137
|
```ruby
|
121
|
-
Lite::Uxid::Irreversible::Ulid.encode
|
138
|
+
Lite::Uxid::Irreversible::Ulid.encode #=> '01GJAY9KGR539EZF4QWYEJGSN7'
|
122
139
|
```
|
123
140
|
|
124
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
|
data/benchmarks/compare.rb
CHANGED
@@ -6,12 +6,12 @@ require "benchmark/ips"
|
|
6
6
|
require "lite/uxid"
|
7
7
|
|
8
8
|
Benchmark.ips do |x|
|
9
|
-
x.report("
|
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("
|
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
|
-
|
5
|
-
config.
|
6
|
-
config.
|
7
|
-
|
8
|
-
|
9
|
-
config.
|
10
|
-
config.
|
11
|
-
|
12
|
-
|
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
|
data/lib/lite/uxid/base.rb
CHANGED
@@ -9,7 +9,7 @@ module Lite
|
|
9
9
|
|
10
10
|
class Configuration
|
11
11
|
|
12
|
-
attr_accessor :hashid_charset, :
|
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
|
@@ -6,12 +6,15 @@ module Lite
|
|
6
6
|
class Uuid < Base
|
7
7
|
|
8
8
|
def encode
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
@@ -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) <<
|
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) >>
|
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.
|
39
|
+
len = encoded_id.length
|
38
40
|
max = len - 1
|
39
41
|
|
40
42
|
while pos < len
|
data/lib/lite/uxid/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2024-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|