lite-uxid 1.2.0 → 1.4.0

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: 8119c92432950cdd4fd849aafd041832a8f4ceee022c7f38009681726bb1181a
4
- data.tar.gz: 121d26ff5203b65b8a4b148f9f82aad5585c4baeae6ae1008e71cc057d6fc1f8
3
+ metadata.gz: 1f8fdc0fac3f66d26f1fa5ed7944775912fedb7ef4a8c1d8d582ca3b8ddad11c
4
+ data.tar.gz: 9e0b2729d115fab68c449034c95ce38706680eaf0327a1f46bea2e4afb654a66
5
5
  SHA512:
6
- metadata.gz: 4ed1ddf45549eef5ee6b6950b000272b8d62dfa8ac5b403fa5e6ffc70dfabd9a03978a7e96259184b3222b42e3b1dc240e44984ee89086cfe3f396e7fcfa3d8c
7
- data.tar.gz: c63df74d2affbda2f3fefc86a0b5d44364dfef7417b22c6c56f7d411808d3935d1b26f06de92d8699f3ababaf8c84a9e3a0149123a3ed66d52e92bf59f064192
6
+ metadata.gz: 8cdb90bf7523761fe7fe9673195d888419ffc5fd0199c52bd353e39b779746b5e4bbe7e18232baf97a8bfd106afb0eb593e68818eac886aa5cc17cfa20a6bc56
7
+ data.tar.gz: 07c960b84a617349cd65c74639dbf3fee6e82ea519d0bf64ff3f52dcb75b8e6b8ff3d06c935cd58170e5987ed06ff5b47913bce7866964e24abe935c6749b383
data/CHANGELOG.md CHANGED
@@ -6,9 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.4.0] - 2022-11-20
10
+ ### Changed
11
+ - Improved global config flexibility
12
+ - Update config generator to generate dynamic salt
13
+
14
+ ## [1.3.0] - 2022-11-20
15
+ ### Added
16
+ - Added uuid option
17
+
9
18
  ## [1.2.0] - 2022-11-19
10
19
  ### Added
11
- - Added individual character and length options
20
+ - Added individual character and size options
12
21
  ### Changed
13
22
  - Improved docs
14
23
  - Improved internal setup
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lite-uxid (1.2.0)
4
+ lite-uxid (1.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  Lite::Uxid is a library for generating or obfuscating ID's based on different patterns.
7
7
  It's very useful to hide the number of resources in your database and protect against enumeration attacks.
8
+ By default, it implements websafe variants of each type.
8
9
 
9
10
  ## Installation
10
11
 
@@ -25,9 +26,11 @@ Or install it yourself as:
25
26
  ## Table of Contents
26
27
 
27
28
  * [Configuration](#configuration)
29
+ * [Usage](#usage)
28
30
  * [Hashid](#hashid)
29
31
  * [NanoID](#nanoid)
30
32
  * [ULID](#ulid)
33
+ * [UUID](#uuid)
31
34
  * [Options](#options)
32
35
  * [ActiveRecord](#active_record)
33
36
  * [Benchmarks](#benchmarks)
@@ -39,37 +42,60 @@ Or install it yourself as:
39
42
 
40
43
  ```ruby
41
44
  Lite::Uxid.configure do |config|
42
- config.encoding_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
43
- config.encoding_salt = 1_369_136
44
- config.hashid_length = 12
45
- config.nanoid_length = 21
46
- config.ulid_length = 26
45
+ config.hashid_charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
46
+ config.hashid_salt = 1_369_136
47
+ config.hashid_size = 16
48
+ config.nanoid_charset = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
49
+ config.nanoid_size = 21
50
+ config.ulid_charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
51
+ config.ulid_size = 26
47
52
  end
48
53
  ```
49
54
 
55
+ ## Usage
56
+
57
+ #### Instance
58
+ ```ruby
59
+ coder = Lite::Uxid::Hashid.new(10, size: 12)
60
+ coder.encode #=> '67wGI0'
61
+ ```
62
+
63
+ #### Class
64
+ ```ruby
65
+ Lite::Uxid::Hashid.decode('67wGI0', size: 12) #=> 10
66
+ ```
67
+
50
68
  ## Hashid
51
69
 
52
- Hashid's are reversible and is the most performant generator.
70
+ [More information](https://hashids.org)
53
71
 
54
72
  ```ruby
55
- Lite::Uxid::Hashid.encode(10) #=> 'q5D8inm0'
56
- Lite::Uxid::Hashid.decode('q5D8inm0') #=> 10
73
+ Lite::Uxid::Hashid.encode(10) #=> '1zWr1m0'
74
+ Lite::Uxid::Hashid.decode('1zWr1m0') #=> 10
57
75
  ```
58
76
 
59
77
  ## NanoID
60
78
 
61
- NanoID are irreversible and are the second fastest ID generator but while unlikely can produce collisions.
79
+ [More information](https://github.com/ai/nanoid)
62
80
 
63
81
  ```ruby
64
- Lite::Uxid::Nanoid.encode #=> '0bmHjB5Gx8FTBqJekX6dS6XIXf'
82
+ Lite::Uxid::Nanoid.encode #=> 'sMuNUa3Cegn6r5GRQ4Ij2'
65
83
  ```
66
84
 
67
85
  ## ULID
68
86
 
69
- ULID are irreversible but provide information outside of just randomness.
87
+ [More information](https://github.com/ulid/spec)
70
88
 
71
89
  ```ruby
72
- Lite::Uxid::Ulid.encode #=> '1mqfg9qa96s8s5f02o1ucf8lcc'
90
+ Lite::Uxid::Ulid.encode #=> '01GJAY9KGR539EZF4QWYEJGSN7'
91
+ ```
92
+
93
+ ## UUID
94
+
95
+ Implements v4 of the specification. [More information](https://en.wikipedia.org/wiki/Universally_unique_identifier)
96
+
97
+ ```ruby
98
+ Lite::Uxid::Uuid.encode #=> '4376a67e-1189-44b3-a599-7f7566bf105b'
73
99
  ```
74
100
 
75
101
  ## Options
@@ -77,7 +103,7 @@ Lite::Uxid::Ulid.encode #=> '1mqfg9qa96s8s5f02o1ucf8lcc'
77
103
  Local options can be passed to override global options.
78
104
 
79
105
  ```ruby
80
- Lite::Uxid::Ulid.encode(chars: 'abc123', length: 12) #=> 'a3b12c12c3ca'
106
+ Lite::Uxid::Ulid.encode(chars: 'abc123', size: 12) #=> 'a3b12c12c3ca'
81
107
  ```
82
108
 
83
109
  ## ActiveRecord
@@ -115,6 +141,13 @@ class User < ActiveRecord::Base
115
141
  end
116
142
  ```
117
143
 
144
+ #### UUID
145
+ ```ruby
146
+ class User < ActiveRecord::Base
147
+ include Lite::Uxid::Record::Uuid
148
+ end
149
+ ```
150
+
118
151
  **Usage**
119
152
 
120
153
  Using one of the mixins above provides a handy method to find records by uxid.
@@ -134,10 +167,15 @@ User.find_by_uxid!('x123') #=> Raises an ActiveRecord::RecordNotFound error if n
134
167
 
135
168
  ## Benchmarks
136
169
 
137
- The classes ranked from fastest to slowest are `Hashid`, `Nanoid`, and `Ulid`.
170
+ The classes ranked from fastest to slowest are `UUID`, `Hashid`, `Nanoid`, and `Ulid`.
138
171
 
139
172
  View how each compares by running the [benchmarks](https://github.com/drexed/lite-uxid/tree/master/benchmarks).
140
173
 
174
+ #### Alternatives
175
+
176
+ Learn more about alternative functions and more advance hashing setups:
177
+ [hashids.org](https://hashids.org)
178
+
141
179
  ## Development
142
180
 
143
181
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -7,16 +7,24 @@ require "lite/uxid"
7
7
 
8
8
  Benchmark.ips do |x|
9
9
  x.report("Hashid") do
10
- Lite::Uxid::Hashid.encode(rand(1..1_000_000))
10
+ id = rand(1..1_000_000)
11
+ Lite::Uxid::Hashid.encode(id)
11
12
  end
12
13
 
13
14
  x.report("NanoID") do
15
+ _id = rand(1..1_000_000) # To simulate the extra work from `rand`
14
16
  Lite::Uxid::Nanoid.encode
15
17
  end
16
18
 
17
19
  x.report("ULID") do
20
+ _id = rand(1..1_000_000) # To simulate the extra work from `rand`
18
21
  Lite::Uxid::Ulid.encode
19
22
  end
20
23
 
24
+ x.report("UUID") do
25
+ _id = rand(1..1_000_000) # To simulate the extra work from `rand`
26
+ Lite::Uxid::Uuid.encode
27
+ end
28
+
21
29
  x.compare!
22
30
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Lite::Uxid.configure do |config|
4
- config.encoding_chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
5
- config.encoding_salt = 1_369_136
6
- config.hashid_length = 12
7
- config.nanoid_length = 21
8
- config.ulid_length = 26
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.ulid_charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
10
+ config.ulid_size = 26
9
11
  end
@@ -5,14 +5,16 @@ module Lite
5
5
 
6
6
  class Configuration
7
7
 
8
- attr_accessor :encoding_chars, :encoding_salt, :hashid_length, :nanoid_length, :ulid_length
8
+ attr_accessor :hashid_charset, :hashid_salt, :hashid_size, :nanoid_charset, :nanoid_size, :ulid_charset, :ulid_size
9
9
 
10
10
  def initialize
11
- @encoding_chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
12
- @encoding_salt = 1_369_136
13
- @hashid_length = 12
14
- @nanoid_length = 21
15
- @ulid_length = 26
11
+ @hashid_charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
12
+ @hashid_salt = 1_369_136
13
+ @hashid_size = 16
14
+ @nanoid_charset = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
15
+ @nanoid_size = 21
16
+ @ulid_charset = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
17
+ @ulid_size = 26
16
18
  end
17
19
 
18
20
  end
@@ -5,11 +5,11 @@ module Lite
5
5
  class Hashid < Reversible
6
6
 
7
7
  def encode
8
- encode_chars((id + coder_salt) << coder_length)
8
+ encode_chars((id + coder_salt) << coder_size)
9
9
  end
10
10
 
11
11
  def decode
12
- (decode_chars(id) >> coder_length) - coder_salt
12
+ (decode_chars(id) >> coder_size) - coder_salt
13
13
  end
14
14
 
15
15
  private
@@ -21,8 +21,8 @@ module Lite
21
21
  str = ""
22
22
 
23
23
  while decoded_id.positive?
24
- str = "#{coder_chars[decoded_id % coder_base]}#{str}"
25
- decoded_id /= coder_base
24
+ str = "#{coder_charset[decoded_id % coder_length]}#{str}"
25
+ decoded_id /= coder_length
26
26
  end
27
27
 
28
28
  str
@@ -31,12 +31,12 @@ module Lite
31
31
  def decode_chars(encoded_id)
32
32
  pos = 0
33
33
  num = 0
34
- len = encoded_id.length
34
+ len = encoded_id.size
35
35
  max = len - 1
36
36
 
37
37
  while pos < len
38
- pow = coder_base**(max - pos)
39
- num += coder_chars.index(encoded_id[pos]) * pow
38
+ pow = coder_length**(max - pos)
39
+ num += coder_charset.index(encoded_id[pos]) * pow
40
40
  pos += 1
41
41
  end
42
42
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "securerandom" unless defined?(SecureRandom)
4
+
3
5
  module Lite
4
6
  module Uxid
5
7
  class Irreversible
@@ -34,14 +36,14 @@ module Lite
34
36
 
35
37
  private
36
38
 
37
- def coder_base
38
- @coder_base ||= coder_chars.length
39
+ def coder_bytes
40
+ @coder_bytes ||= SecureRandom.random_bytes(coder_size).bytes
39
41
  end
40
42
 
41
- def coder_chars
42
- @coder_chars ||=
43
- opts.delete(:chars) ||
44
- Lite::Uxid.configuration.encoding_chars
43
+ def coder_charset
44
+ @coder_charset ||=
45
+ opts.delete(:charset) ||
46
+ Lite::Uxid.configuration.send("#{coder_class.downcase}_charset")
45
47
  end
46
48
 
47
49
  def coder_class
@@ -49,15 +51,19 @@ module Lite
49
51
  end
50
52
 
51
53
  def coder_length
52
- @coder_length ||=
53
- opts.delete(:length) ||
54
- Lite::Uxid.configuration.send("#{coder_class.downcase}_length")
54
+ @coder_length ||= coder_charset.size
55
55
  end
56
56
 
57
57
  def coder_salt
58
58
  @coder_salt ||=
59
59
  opts.delete(:salt) ||
60
- Lite::Uxid.configuration.encoding_salt
60
+ Lite::Uxid.configuration.send("#{coder_class.downcase}_salt")
61
+ end
62
+
63
+ def coder_size
64
+ @coder_size ||=
65
+ opts.delete(:size) ||
66
+ Lite::Uxid.configuration.send("#{coder_class.downcase}_size")
61
67
  end
62
68
 
63
69
  end
@@ -5,7 +5,9 @@ module Lite
5
5
  class Nanoid < Irreversible
6
6
 
7
7
  def encode
8
- coder_chars.chars.sample(coder_length).join
8
+ (0...coder_size).each_with_object(+"") do |i, str|
9
+ str << coder_charset[coder_bytes[i] & 63]
10
+ end
9
11
  end
10
12
 
11
13
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support" unless defined?(ActiveSupport)
4
+
5
+ module Lite
6
+ module Uxid
7
+ module Record
8
+ module Uuid
9
+
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ before_create :callback_generate_uxid!, if: proc { respond_to?(:uxid) && !uxid? }
14
+ end
15
+
16
+ private
17
+
18
+ def callback_generate_uxid!
19
+ self.uxid = Lite::Uxid::Uuid.encode
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "securerandom" unless defined?(SecureRandom)
4
-
5
3
  module Lite
6
4
  module Uxid
7
5
  class Ulid < Irreversible
@@ -10,11 +8,11 @@ module Lite
10
8
 
11
9
  def encode
12
10
  oct = octect
13
- ele = "0" * coder_length
14
- pos = coder_length - 1
11
+ ele = "0" * coder_size
12
+ pos = coder_size - 1
15
13
 
16
14
  while oct.positive?
17
- ele[pos] = coder_chars[oct & MASK]
15
+ ele[pos] = coder_charset[oct & MASK]
18
16
  oct >>= 5
19
17
  pos -= 1
20
18
  end
@@ -35,7 +33,7 @@ module Lite
35
33
 
36
34
  def unixtime_ms
37
35
  time = Time.respond_to?(:current) ? Time.current : Time.now
38
- (time.to_f * 1_000).to_i
36
+ time.to_i * 1_000
39
37
  end
40
38
 
41
39
  def unixtime_48bit
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lite
4
+ module Uxid
5
+ class Uuid < Irreversible
6
+
7
+ def encode
8
+ SecureRandom.uuid
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -3,7 +3,7 @@
3
3
  module Lite
4
4
  module Uxid
5
5
 
6
- VERSION = "1.2.0"
6
+ VERSION = "1.4.0"
7
7
 
8
8
  end
9
9
  end
data/lib/lite/uxid.rb CHANGED
@@ -9,6 +9,8 @@ require "lite/uxid/reversible"
9
9
  require "lite/uxid/record/hashid"
10
10
  require "lite/uxid/record/nanoid"
11
11
  require "lite/uxid/record/ulid"
12
+ require "lite/uxid/record/uuid"
12
13
  require "lite/uxid/hashid"
13
14
  require "lite/uxid/nanoid"
14
15
  require "lite/uxid/ulid"
16
+ require "lite/uxid/uuid"
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: 1.2.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Gomez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-19 00:00:00.000000000 Z
11
+ date: 2022-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -224,8 +224,10 @@ files:
224
224
  - lib/lite/uxid/record/hashid.rb
225
225
  - lib/lite/uxid/record/nanoid.rb
226
226
  - lib/lite/uxid/record/ulid.rb
227
+ - lib/lite/uxid/record/uuid.rb
227
228
  - lib/lite/uxid/reversible.rb
228
229
  - lib/lite/uxid/ulid.rb
230
+ - lib/lite/uxid/uuid.rb
229
231
  - lib/lite/uxid/version.rb
230
232
  - lite-uxid.gemspec
231
233
  homepage: http://drexed.github.io/lite-uxid