opaque_id 1.3.0 → 1.6.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: 0b3fe09fbe6c8dd3f161f8067f1f4159b20d66987d4f83a1649bfebfe2d68af1
4
- data.tar.gz: 3887547bac4c747e9c95b3ff1bbe456ea001d4e0a2432a2186d7a1343f3a40aa
3
+ metadata.gz: 016b3d2bbd7ae3af1ba38973c0b590164d7be1a4bd60a8c0e0379cfca1c9dc0f
4
+ data.tar.gz: 2924779f8769585995732ce79da51b8a1171c0b22fd33636c6476f77815adb44
5
5
  SHA512:
6
- metadata.gz: d3a0326565ef4d064bc651805c9126d313d22cfffbc26fb10ce5f38a9be794a3d67611838465d74eb59e27313bf8a2db1f1669055b79410e9c4c1cbfd6697a1b
7
- data.tar.gz: afe1a2e68f187435cd3efe01871f926b191335bf3bf19958afe66c6e8e873321809e17eb699ff3f6d58cb6175d3296288abdaaa5d8c2b9ccc0ab87cff8c99fe9
6
+ metadata.gz: 82206f53378e08c302fbb9bd56caf94238e3b0780b6a271732d00d04f0e7e37136c1c6c941ef58fe6c6fffd154c7ce1b82c0b12b76240d23399007d34d81a0bd
7
+ data.tar.gz: b5d588f50a7a2337b42fc4e021b9aef658cf3e9f92c64fe5c21c7bf901560d5575b48c05fe72edefa77112175357562b0497c4c3d2ba73dd23be2165b6eadd87
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "1.3.0"
2
+ ".": "1.6.0"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -5,6 +5,142 @@ All notable changes to the OpaqueId gem will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.6.0](https://github.com/nyaggah/opaque_id/compare/opaque_id-v1.5.0...opaque_id/v1.6.0) (2025-10-03)
9
+
10
+
11
+ ### Features
12
+
13
+ * add external links to sidebar using JavaScript ([cd77079](https://github.com/nyaggah/opaque_id/commit/cd770795936ca76633a18f80cba8482ec09db8e2))
14
+ * add SLUG_LIKE_ALPHABET as default for URL-safe IDs ([1e52b17](https://github.com/nyaggah/opaque_id/commit/1e52b174d70ca72b74badf399401605b307e3604))
15
+ * add Table of Contents to all documentation pages ([9472175](https://github.com/nyaggah/opaque_id/commit/94721752270211d5b7db460da61d79a8a81218b2))
16
+ * complete Table of Contents implementation ([5b037e4](https://github.com/nyaggah/opaque_id/commit/5b037e42692803204bc4d8991b6d2e0c9639a05c))
17
+ * implement dynamic copyright year ([b86cea6](https://github.com/nyaggah/opaque_id/commit/b86cea66e60939377c6b0a67c1d385c9bf4bece3))
18
+ * improve documentation site theme and navigation ([304f845](https://github.com/nyaggah/opaque_id/commit/304f845a47397ea2a15f12d2c635144b39be431b))
19
+ * improve generator API and add custom column configuration ([5c1a570](https://github.com/nyaggah/opaque_id/commit/5c1a5703dee269f6985d26096942c086787296f3))
20
+ * initial release of OpaqueId gem v0.1.0 ([3a90274](https://github.com/nyaggah/opaque_id/commit/3a9027403552f8160e3aaf413d1e99ce8c63bbe4))
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * add frozen string literal comment to docs/Gemfile ([2d653a7](https://github.com/nyaggah/opaque_id/commit/2d653a7bbc071e67e94e63ebc1602768b8d04456))
26
+ * add Release Please manifest and update workflow configuration ([f33ce6c](https://github.com/nyaggah/opaque_id/commit/f33ce6c96805b6c670cd1eedf5ebed2a46e8ffa6))
27
+ * add required permissions for Release Please job ([cdf8d2b](https://github.com/nyaggah/opaque_id/commit/cdf8d2bfc5dbea9a9ec40411a988191ba91913fa))
28
+ * configure just-the-docs theme for GitHub Pages compatibility ([c2fb96c](https://github.com/nyaggah/opaque_id/commit/c2fb96c46e99fd5287520e01c3bc2dd7bd5d4817))
29
+ * correct aux_links configuration format ([61b3fb9](https://github.com/nyaggah/opaque_id/commit/61b3fb9441ce3cfc3cf30637c277d19135f89dab))
30
+ * correct release-please tag format ([b4c31e5](https://github.com/nyaggah/opaque_id/commit/b4c31e5d0f4878878dd728e82fe9f5eb09ce5b82))
31
+ * improve publish workflow trigger reliability ([9c6e240](https://github.com/nyaggah/opaque_id/commit/9c6e2402474d8ecf8a3f754a9f2ca149a63bf1d1))
32
+ * improve statistical test reliability for CI ([c9b0d52](https://github.com/nyaggah/opaque_id/commit/c9b0d52fb4e9559aad489fcf58bdff1917d613a6))
33
+ * remove unsupported Release Please configuration parameters ([e3b0d2a](https://github.com/nyaggah/opaque_id/commit/e3b0d2ac96b905316a78992004fae83423991632))
34
+ * resolve CSS linting warnings ([d01e8c0](https://github.com/nyaggah/opaque_id/commit/d01e8c05628b7f2bd8b39a13325112168cf4e689))
35
+ * resolve dependency version conflicts and improve test robustness ([af43e13](https://github.com/nyaggah/opaque_id/commit/af43e13393a452f11ce32bafb26a267d1460736c))
36
+ * resolve TOC rendering and improve workflow configuration ([244d532](https://github.com/nyaggah/opaque_id/commit/244d5321e5b18091d8599bd772a28f5a30239c80))
37
+ * update deprecated platform specifications in docs/Gemfile ([cf96134](https://github.com/nyaggah/opaque_id/commit/cf9613499150dd7152bff38aa8f8fe7ab9923eb5))
38
+ * use correct aux_links format ([d4a4bc0](https://github.com/nyaggah/opaque_id/commit/d4a4bc0c11bc66b661034915b471ed762611d821))
39
+
40
+
41
+ ### Documentation
42
+
43
+ * final cleanup of over-inflated claims ([795b5b0](https://github.com/nyaggah/opaque_id/commit/795b5b0071a098f718a40e84e81ceba4525b8d3b))
44
+ * implement comprehensive documentation site with dark theme ([19cc9e3](https://github.com/nyaggah/opaque_id/commit/19cc9e30c584658559c5404a4518e871039cc223))
45
+ * implement comprehensive documentation site with dark theme ([a249c6a](https://github.com/nyaggah/opaque_id/commit/a249c6ad2253439f0d070620a914ff87597cf7cb))
46
+ * tone down over-inflated claims and remove unsubstantiated benchmarks ([6536b87](https://github.com/nyaggah/opaque_id/commit/6536b87f9a9c2049497328319641ff21368c6032))
47
+ * tone down pretentious language in algorithms intro ([58c0caf](https://github.com/nyaggah/opaque_id/commit/58c0caf116228401b6218ec589a35b350d068b49))
48
+
49
+
50
+ ### Styles
51
+
52
+ * improve code formatting in generator ([ce52021](https://github.com/nyaggah/opaque_id/commit/ce52021cd60e3594dc1ee34e5b96d48568008b5a))
53
+
54
+
55
+ ### Miscellaneous Chores
56
+
57
+ * configure just-the-docs theme ([3dfcac8](https://github.com/nyaggah/opaque_id/commit/3dfcac88099e65e61931e558e9242050bdbf0bc9))
58
+ * **main:** release 1.0.0 ([43282c5](https://github.com/nyaggah/opaque_id/commit/43282c5865aae3f136c9eaa49f013066a2359826))
59
+ * **main:** release 1.0.0 ([b8271ad](https://github.com/nyaggah/opaque_id/commit/b8271ad43cf6fab4687276258f0105c06a87bff7))
60
+ * **main:** release 1.0.1 ([4ee2e2c](https://github.com/nyaggah/opaque_id/commit/4ee2e2c69905e71d6c5048617af09b65cbb9e12a))
61
+ * **main:** release 1.0.1 ([e6cd2f8](https://github.com/nyaggah/opaque_id/commit/e6cd2f8f8ff545ad3010598488f71956e36a88c5))
62
+ * **main:** release 1.0.2 ([d5c7423](https://github.com/nyaggah/opaque_id/commit/d5c7423cf06ae7638d95cdd29b2631049efed727))
63
+ * **main:** release 1.0.2 ([365dff8](https://github.com/nyaggah/opaque_id/commit/365dff87a044aa967906866d6ace8d1ccad08c78))
64
+ * **main:** release opaque_id 1.1.0 ([df65c79](https://github.com/nyaggah/opaque_id/commit/df65c79d0efaee1dcd89b8af2f1b1c712c3cc2cd))
65
+ * **main:** release opaque_id 1.1.0 ([e2a4ee0](https://github.com/nyaggah/opaque_id/commit/e2a4ee0fd2d31132bc5bc0de6b6115f3ceae8afb))
66
+ * **main:** release opaque_id 1.2.0 ([1987b07](https://github.com/nyaggah/opaque_id/commit/1987b07b3db92216f3fbbe807c3ad66ca105866e))
67
+ * **main:** release opaque_id 1.2.0 ([aacd20a](https://github.com/nyaggah/opaque_id/commit/aacd20aa5eaa1fe2fa76d89cc6bdab26214b744d))
68
+ * **main:** release opaque_id 1.3.0 ([964b1b4](https://github.com/nyaggah/opaque_id/commit/964b1b421b1fac3fe43b15549e0e6b216b600357))
69
+ * **main:** release opaque_id 1.3.0 ([76453ad](https://github.com/nyaggah/opaque_id/commit/76453ad18b2d2b81548e49dafb5dde6fb52abcca))
70
+ * **main:** release opaque_id 1.4.0 ([6c3ccd1](https://github.com/nyaggah/opaque_id/commit/6c3ccd108b3eea0bbf0ac71fda4ccc0e47e97b95))
71
+ * **main:** release opaque_id 1.4.0 ([3d9d818](https://github.com/nyaggah/opaque_id/commit/3d9d818b34771ad1ca729f3f9b443784a6965568))
72
+ * **main:** release opaque_id 1.5.0 ([113af74](https://github.com/nyaggah/opaque_id/commit/113af74dda07330bf7108977147362385dc806ae))
73
+ * **main:** release opaque_id 1.5.0 ([ff14fe9](https://github.com/nyaggah/opaque_id/commit/ff14fe92d94cf4ecbe5aaeb31ad6cd044bfa89d0))
74
+ * remove tasks/ directory from source control ([e007ead](https://github.com/nyaggah/opaque_id/commit/e007ead90fa3fbb62ab17e334563e69899afb259))
75
+ * sync version to 1.0.2 ([2f870c8](https://github.com/nyaggah/opaque_id/commit/2f870c89d486f0a5cda8ef37e5544c29c8fa2919))
76
+ * update author name and GitHub URLs ([e911548](https://github.com/nyaggah/opaque_id/commit/e911548e89e1e60ac3281157059f7c7b812750bd))
77
+ * update bundle and add Linux platform support ([661842f](https://github.com/nyaggah/opaque_id/commit/661842f0ba66ce36962bb11f75a1b0e35eb5a3e7))
78
+ * update Gemfile.lock after dependency check ([058281f](https://github.com/nyaggah/opaque_id/commit/058281f6e07f3c9a1057c6fbeb0200bccf221558))
79
+
80
+
81
+ ### Code Refactoring
82
+
83
+ * improve generator code quality and resolve RuboCop issues ([b658bbc](https://github.com/nyaggah/opaque_id/commit/b658bbcb29f6c0134f2bf256b24c5b3c2bccb265))
84
+ * integrate Release Please into main CI workflow ([8a0b189](https://github.com/nyaggah/opaque_id/commit/8a0b189a8bfbfcc07275c9bdda3397ff367b2054))
85
+ * simplify external links implementation ([5cb84c1](https://github.com/nyaggah/opaque_id/commit/5cb84c1e8952a0fd1aa4b9089b9ff11829dc397c))
86
+
87
+
88
+ ### Tests
89
+
90
+ * add test for lowercase model names ([8ef4675](https://github.com/nyaggah/opaque_id/commit/8ef4675a0698d2cda054084360c9e80d956ddb14))
91
+ * update tests for SLUG_LIKE_ALPHABET defaults ([d7296c7](https://github.com/nyaggah/opaque_id/commit/d7296c77b1b7a995e7a42b3ba546fdeb8e41c297))
92
+ * update tests for SLUG_LIKE_ALPHABET defaults ([d1f8f26](https://github.com/nyaggah/opaque_id/commit/d1f8f26e7be80f6cbefc98563c0ffa45033372dc))
93
+
94
+ ## [1.5.0](https://github.com/nyaggah/opaque_id/compare/opaque_id/v1.4.0...opaque_id/v1.5.0) (2025-10-03)
95
+
96
+
97
+ ### Features
98
+
99
+ * add SLUG_LIKE_ALPHABET as default for URL-safe IDs ([1e52b17](https://github.com/nyaggah/opaque_id/commit/1e52b174d70ca72b74badf399401605b307e3604))
100
+
101
+
102
+ ### Bug Fixes
103
+
104
+ * resolve TOC rendering and improve workflow configuration ([244d532](https://github.com/nyaggah/opaque_id/commit/244d5321e5b18091d8599bd772a28f5a30239c80))
105
+
106
+
107
+ ### Documentation
108
+
109
+ * final cleanup of over-inflated claims ([795b5b0](https://github.com/nyaggah/opaque_id/commit/795b5b0071a098f718a40e84e81ceba4525b8d3b))
110
+ * tone down over-inflated claims and remove unsubstantiated benchmarks ([6536b87](https://github.com/nyaggah/opaque_id/commit/6536b87f9a9c2049497328319641ff21368c6032))
111
+ * tone down pretentious language in algorithms intro ([58c0caf](https://github.com/nyaggah/opaque_id/commit/58c0caf116228401b6218ec589a35b350d068b49))
112
+
113
+
114
+ ### Miscellaneous Chores
115
+
116
+ * remove tasks/ directory from source control ([e007ead](https://github.com/nyaggah/opaque_id/commit/e007ead90fa3fbb62ab17e334563e69899afb259))
117
+
118
+
119
+ ### Tests
120
+
121
+ * update tests for SLUG_LIKE_ALPHABET defaults ([d7296c7](https://github.com/nyaggah/opaque_id/commit/d7296c77b1b7a995e7a42b3ba546fdeb8e41c297))
122
+ * update tests for SLUG_LIKE_ALPHABET defaults ([d1f8f26](https://github.com/nyaggah/opaque_id/commit/d1f8f26e7be80f6cbefc98563c0ffa45033372dc))
123
+
124
+ ## [1.4.0](https://github.com/nyaggah/opaque_id/compare/opaque_id/v1.3.0...opaque_id/v1.4.0) (2025-10-02)
125
+
126
+
127
+ ### Features
128
+
129
+ * add external links to sidebar using JavaScript ([cd77079](https://github.com/nyaggah/opaque_id/commit/cd770795936ca76633a18f80cba8482ec09db8e2))
130
+ * add Table of Contents to all documentation pages ([9472175](https://github.com/nyaggah/opaque_id/commit/94721752270211d5b7db460da61d79a8a81218b2))
131
+ * complete Table of Contents implementation ([5b037e4](https://github.com/nyaggah/opaque_id/commit/5b037e42692803204bc4d8991b6d2e0c9639a05c))
132
+
133
+
134
+ ### Bug Fixes
135
+
136
+ * correct aux_links configuration format ([61b3fb9](https://github.com/nyaggah/opaque_id/commit/61b3fb9441ce3cfc3cf30637c277d19135f89dab))
137
+ * use correct aux_links format ([d4a4bc0](https://github.com/nyaggah/opaque_id/commit/d4a4bc0c11bc66b661034915b471ed762611d821))
138
+
139
+
140
+ ### Code Refactoring
141
+
142
+ * simplify external links implementation ([5cb84c1](https://github.com/nyaggah/opaque_id/commit/5cb84c1e8952a0fd1aa4b9089b9ff11829dc397c))
143
+
8
144
  ## [1.3.0](https://github.com/nyaggah/opaque_id/compare/opaque_id/v1.2.0...opaque_id/v1.3.0) (2025-10-02)
9
145
 
10
146
 
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)
5
5
  [![Gem Downloads](https://img.shields.io/gem/dt/opaque_id)](https://rubygems.org/gems/opaque_id)
6
6
 
7
- A Ruby gem for generating cryptographically secure, collision-free opaque IDs for ActiveRecord models. OpaqueId provides a drop-in replacement for `nanoid.rb` using Ruby's built-in `SecureRandom` methods with optimized algorithms for unbiased distribution.
7
+ A simple Ruby gem for generating secure, opaque IDs for ActiveRecord models. OpaqueId provides a drop-in replacement for `nanoid.rb` using Ruby's built-in `SecureRandom` methods, with slug-like IDs as the default for optimal URL safety and user experience.
8
8
 
9
9
  ## Table of Contents
10
10
 
@@ -87,12 +87,12 @@ A Ruby gem for generating cryptographically secure, collision-free opaque IDs fo
87
87
  ## Features
88
88
 
89
89
  - **🔐 Cryptographically Secure**: Uses Ruby's `SecureRandom` for secure ID generation
90
- - **⚡ High Performance**: Optimized algorithms with fast paths for 64-character alphabets
91
- - **🎯 Collision-Free**: Built-in collision detection with configurable retry attempts
90
+ - **⚡ Performance Optimized**: Efficient algorithms with fast paths for 64-character alphabets
91
+ - **🎯 Collision Resistant**: Built-in collision detection with configurable retry attempts
92
92
  - **🔧 Highly Configurable**: Customizable alphabet, length, column name, and validation rules
93
- - **🚀 Rails Integration**: Seamless ActiveRecord integration with automatic ID generation
93
+ - **🚀 Rails Integration**: ActiveRecord integration with automatic ID generation
94
94
  - **📦 Rails Generator**: One-command setup with `rails generate opaque_id:install`
95
- - **🧪 Well Tested**: Comprehensive test suite with statistical uniformity tests
95
+ - **🧪 Tested**: Includes test suite with statistical uniformity tests
96
96
  - **📚 Rails 8.0+ Compatible**: Built for modern Rails applications
97
97
 
98
98
  ## Installation
@@ -176,15 +176,34 @@ end
176
176
 
177
177
  # IDs are automatically generated on creation
178
178
  user = User.create!(name: "John Doe")
179
- puts user.opaque_id # => "V1StGXR8_Z5jdHi6B-myT"
179
+ puts user.opaque_id # => "izkpm55j334u8x9y2"
180
180
 
181
181
  # Find by opaque ID
182
- user = User.find_by_opaque_id("V1StGXR8_Z5jdHi6B-myT")
183
- user = User.find_by_opaque_id!("V1StGXR8_Z5jdHi6B-myT") # raises if not found
182
+ user = User.find_by_opaque_id("izkpm55j334u8x9y2")
183
+ user = User.find_by_opaque_id!("izkpm55j334u8x9y2") # raises if not found
184
184
  ```
185
185
 
186
186
  ## Usage
187
187
 
188
+ ### URL-Safe, Double-Click Selectable IDs
189
+
190
+ OpaqueId defaults to generating **slug-like IDs** that are perfect for URLs and user-facing identifiers:
191
+
192
+ - **URL-safe**: No special characters that need encoding
193
+ - **Double-click selectable**: Users can easily select the entire ID
194
+ - **Shorter than UUIDs**: 18 characters vs 36 for UUIDs
195
+ - **Collision resistant**: Built on Ruby's `SecureRandom` for security
196
+
197
+ ```ruby
198
+ # Default generation creates slug-like IDs
199
+ id = OpaqueId.generate
200
+ # => "izkpm55j334u8x9y2" # Perfect for URLs and user selection
201
+
202
+ # Compare to UUIDs
203
+ uuid = SecureRandom.uuid
204
+ # => "7cb776c5-8c12-4b1a-84aa-9941b815d873" # Harder to select, longer
205
+ ```
206
+
188
207
  ### Standalone ID Generation
189
208
 
190
209
  OpaqueId can be used independently of ActiveRecord for generating secure IDs in any Ruby application:
@@ -192,13 +211,13 @@ OpaqueId can be used independently of ActiveRecord for generating secure IDs in
192
211
  #### Basic Usage
193
212
 
194
213
  ```ruby
195
- # Generate with default settings (21 characters, alphanumeric)
214
+ # Generate with default settings (18 characters, slug-like)
196
215
  id = OpaqueId.generate
197
- # => "V1StGXR8_Z5jdHi6B-myT"
216
+ # => "izkpm55j334u8x9y2"
198
217
 
199
218
  # Custom length
200
219
  id = OpaqueId.generate(size: 10)
201
- # => "V1StGXR8_Z5"
220
+ # => "izkpm55j334u"
202
221
 
203
222
  # Custom alphabet
204
223
  id = OpaqueId.generate(alphabet: OpaqueId::STANDARD_ALPHABET)
@@ -210,7 +229,7 @@ id = OpaqueId.generate(size: 8, alphabet: "ABCDEFGH")
210
229
 
211
230
  # Generate multiple IDs
212
231
  ids = 5.times.map { OpaqueId.generate(size: 8) }
213
- # => ["V1StGXR8", "Z5jdHi6B", "myT12345", "ABCdefGH", "IJKlmnoP"]
232
+ # => ["izkpm55j", "334u8x9y", "2abc1234", "def5678g", "hij9klmn"]
214
233
  ```
215
234
 
216
235
  #### Standalone Use Cases
@@ -229,7 +248,7 @@ class BackgroundJob
229
248
  end
230
249
 
231
250
  job_id = BackgroundJob.enqueue(ProcessDataJob, user_id: 123)
232
- # => "V1StGXR8_Z5jd"
251
+ # => "izkpm55j334u8x9y2"
233
252
  ```
234
253
 
235
254
  ##### Temporary File Names
@@ -243,7 +262,7 @@ def create_temp_file(content)
243
262
  end
244
263
 
245
264
  filename = create_temp_file("Hello World")
246
- # => "temp_V1StGXR8.txt"
265
+ # => "temp_izkpm55j334u8x9y2.txt"
247
266
  ```
248
267
 
249
268
  ##### Cache Keys
@@ -264,7 +283,7 @@ user_key = CacheManager.user_cache_key(123)
264
283
  # => "user:V1StGX:123"
265
284
 
266
285
  session_key = CacheManager.session_cache_key
267
- # => "session:V1StGXR8_Z5jdHi6B"
286
+ # => "session:izkpm55j334u8x9y2"
268
287
  ```
269
288
 
270
289
  ##### Webhook Signatures
@@ -281,7 +300,7 @@ class WebhookService
281
300
  end
282
301
 
283
302
  signature = WebhookService.generate_signature({ user_id: 123 })
284
- # => "1703123456:V1StGXR8_Z5jdHi6B:1234567890"
303
+ # => "1703123456:izkpm55j334u8x9y2:1234567890"
285
304
  ```
286
305
 
287
306
  ##### Database Migration IDs
@@ -309,7 +328,7 @@ class EmailService
309
328
  end
310
329
 
311
330
  tracking_id = EmailService.tracking_pixel_id
312
- # => "V1StGXR8Z5jdHi6BmyT12"
331
+ # => "izkpm55j334u8x9y2abc"
313
332
 
314
333
  # Use in email template
315
334
  # <img src="https://example.com/track/#{tracking_id}" width="1" height="1" />
@@ -328,7 +347,7 @@ class ApiLogger
328
347
  end
329
348
 
330
349
  request_id = ApiLogger.log_request("/api/users", { page: 1 })
331
- # => "V1StGXR8_Z5jd"
350
+ # => "izkpm55j334u8x9y2"
332
351
  ```
333
352
 
334
353
  ##### Batch Processing IDs
@@ -350,9 +369,9 @@ class BatchProcessor
350
369
  end
351
370
 
352
371
  batch_id = BatchProcessor.process_batch([1, 2, 3, 4, 5])
353
- # => "V1StGXR8_Z5"
354
- # => Processing item V1StGXR8_Z5_000: 1
355
- # => Processing item V1StGXR8_Z5_001: 2
372
+ # => "izkpm55j334u8x9y2"
373
+ # => Processing item izkpm55j334u8x9y2_000: 1
374
+ # => Processing item izkpm55j334u8x9y2_001: 2
356
375
  # => ...
357
376
  ```
358
377
 
@@ -417,7 +436,7 @@ end
417
436
 
418
437
  # Create a new post - opaque_id is automatically generated
419
438
  post = Post.create!(title: "Hello World", content: "This is my first post")
420
- puts post.opaque_id # => "V1StGXR8_Z5jdHi6B-myT"
439
+ puts post.opaque_id # => "izkpm55j334u8x9y2"
421
440
 
422
441
  # Create multiple posts
423
442
  posts = Post.create!([
@@ -427,9 +446,9 @@ posts = Post.create!([
427
446
  ])
428
447
 
429
448
  posts.each { |p| puts "#{p.title}: #{p.opaque_id}" }
430
- # => Post 1: V1StGXR8_Z5jdHi6B-myT
431
- # => Post 2: Z5jdHi6B-myT12345
432
- # => Post 3: myT12345-ABCdefGH
449
+ # => Post 1: izkpm55j334u8x9y2
450
+ # => Post 2: 334u8x9y2abc1234
451
+ # => Post 3: abc1234def5678gh
433
452
  ```
434
453
 
435
454
  #### Custom Configuration
@@ -482,7 +501,7 @@ class ApiKey < ApplicationRecord
482
501
  self.opaque_id_max_retry = 10
483
502
  end
484
503
 
485
- # Generated API keys will look like: "V1StGXR8Z5jdHi6BmyT1234567890AB"
504
+ # Generated API keys will look like: "izkpm55j334u8x9y2abc1234def5678gh"
486
505
  ```
487
506
 
488
507
  ##### Short URL Configuration
@@ -529,7 +548,7 @@ class Upload < ApplicationRecord
529
548
  self.opaque_id_purge_chars = ['/', '\\', ':', '*', '?', '"', '<', '>', '|']
530
549
  end
531
550
 
532
- # Generated filenames will look like: "V1StGXR8-Z5jd"
551
+ # Generated filenames will look like: "izkpm55j334u8x9y2"
533
552
  ```
534
553
 
535
554
  ##### Session Token Configuration
@@ -554,7 +573,7 @@ class Session < ApplicationRecord
554
573
  self.opaque_id_max_retry = 8
555
574
  end
556
575
 
557
- # Generated session tokens will look like: "V1StGXR8_Z5jdHi6B-myT123"
576
+ # Generated session tokens will look like: "izkpm55j334u8x9y2abc123"
558
577
  ```
559
578
 
560
579
  ##### Custom Alphabet Examples
@@ -592,7 +611,7 @@ end
592
611
 
593
612
  ```ruby
594
613
  # Find by opaque ID (returns nil if not found)
595
- user = User.find_by_opaque_id("V1StGXR8_Z5jdHi6B-myT")
614
+ user = User.find_by_opaque_id("izkpm55j334u8x9y2")
596
615
  if user
597
616
  puts "Found user: #{user.name}"
598
617
  else
@@ -600,14 +619,14 @@ else
600
619
  end
601
620
 
602
621
  # Find by opaque ID (raises ActiveRecord::RecordNotFound if not found)
603
- user = User.find_by_opaque_id!("V1StGXR8_Z5jdHi6B-myT")
622
+ user = User.find_by_opaque_id!("izkpm55j334u8x9y2")
604
623
  puts "Found user: #{user.name}"
605
624
 
606
625
  # Use in controllers for public-facing URLs
607
626
  class PostsController < ApplicationController
608
627
  def show
609
628
  @post = Post.find_by_opaque_id!(params[:id])
610
- # This allows URLs like /posts/V1StGXR8_Z5jdHi6B-myT
629
+ # This allows URLs like /posts/izkpm55j334u8x9y2
611
630
  end
612
631
  end
613
632
 
@@ -672,8 +691,8 @@ OpaqueId provides comprehensive configuration options to customize ID generation
672
691
  - **Performance**: Longer IDs are more secure but use more storage
673
692
  - **Examples**:
674
693
  - `6` → Short URLs: `"V1StGX"`
675
- - `21` → Default: `"V1StGXR8_Z5jdHi6B-myT"`
676
- - `32` → API Keys: `"V1StGXR8_Z5jdHi6B-myT1234567890AB"`
694
+ - `18` → Default: `"izkpm55j334u8x9y2"`
695
+ - `32` → API Keys: `"izkpm55j334u8x9y2abc1234def5678gh"`
677
696
 
678
697
  #### `opaque_id_alphabet`
679
698
 
@@ -691,7 +710,7 @@ OpaqueId provides comprehensive configuration options to customize ID generation
691
710
  - **Purpose**: Ensures IDs start with a letter for better readability
692
711
  - **Use Cases**: When IDs are user-facing or need to be easily readable
693
712
  - **Performance**: Slight overhead due to rejection sampling
694
- - **Example**: `true` → `"V1StGXR8_Z5jdHi6B-myT"`, `false` → `"1StGXR8_Z5jdHi6B-myT"`
713
+ - **Example**: `true` → `"izkpm55j334u8x9y2"`, `false` → `"zkpm55j334u8x9y2"`
695
714
 
696
715
  #### `opaque_id_purge_chars`
697
716
 
@@ -744,7 +763,7 @@ OpaqueId::ALPHANUMERIC_ALPHABET
744
763
 
745
764
  ```ruby
746
765
  OpaqueId.generate(size: 8, alphabet: OpaqueId::ALPHANUMERIC_ALPHABET)
747
- # => "V1StGXR8"
766
+ # => "izkpm55j"
748
767
  ```
749
768
 
750
769
  ### `STANDARD_ALPHABET`
@@ -932,41 +951,14 @@ def generate(size:, alphabet:)
932
951
  end
933
952
  ```
934
953
 
935
- ## Performance Benchmarks
936
-
937
- ### Generation Speed (IDs per second)
938
-
939
- | Alphabet Size | Algorithm | Performance | Relative Speed |
940
- | ------------- | --------- | ------------------ | --------------- |
941
- | 64 characters | Fast Path | ~2,500,000 IDs/sec | 100% (baseline) |
942
- | 62 characters | Unbiased | ~1,200,000 IDs/sec | 48% |
943
- | 36 characters | Unbiased | ~1,100,000 IDs/sec | 44% |
944
- | 26 characters | Unbiased | ~1,000,000 IDs/sec | 40% |
945
- | 10 characters | Unbiased | ~900,000 IDs/sec | 36% |
946
-
947
- _Benchmarks run on Ruby 3.2.0, generating 21-character IDs_
948
-
949
- ### Memory Usage
950
-
951
- | Algorithm | Memory per ID | Memory per 1M IDs |
952
- | --------- | ------------- | ----------------- |
953
- | Fast Path | ~21 bytes | ~21 MB |
954
- | Unbiased | ~21 bytes | ~21 MB |
955
-
956
- _Memory usage is consistent regardless of algorithm choice_
957
-
958
- ### Collision Probability
959
-
960
- For 21-character IDs with different alphabets:
954
+ ## Performance Characteristics
961
955
 
962
- | Alphabet | Characters | Collision Probability (1 in) |
963
- | --------------------- | ---------- | ---------------------------- |
964
- | STANDARD_ALPHABET | 64 | 2.9 × 10^37 |
965
- | ALPHANUMERIC_ALPHABET | 62 | 1.4 × 10^37 |
966
- | Numeric (0-9) | 10 | 1.0 × 10^21 |
967
- | Binary (0-1) | 2 | 2.1 × 10^6 |
956
+ OpaqueId is designed for efficient ID generation with different performance characteristics based on alphabet size:
968
957
 
969
- _Collision probability calculated using birthday paradox formula_
958
+ - **64-character alphabets**: Use optimized bitwise operations for faster generation
959
+ - **Other alphabets**: Use rejection sampling for unbiased distribution with slight overhead
960
+ - **Memory usage**: Scales linearly with ID length
961
+ - **Collision resistance**: Extremely low probability for typical use cases
970
962
 
971
963
  ### Performance Characteristics
972
964
 
@@ -975,7 +967,7 @@ _Collision probability calculated using birthday paradox formula_
975
967
  - **Time Complexity**: O(n) where n = ID length
976
968
  - **Space Complexity**: O(n)
977
969
  - **Rejection Rate**: 0% (no rejections)
978
- - **Distribution**: Perfect uniform
970
+ - **Distribution**: Uniform distribution
979
971
  - **Best For**: High-performance applications, short URLs
980
972
 
981
973
  #### Unbiased Path (other alphabets)
@@ -983,7 +975,7 @@ _Collision probability calculated using birthday paradox formula_
983
975
  - **Time Complexity**: O(n × (1 + rejection_rate)) where rejection_rate ≈ 0.01
984
976
  - **Space Complexity**: O(n)
985
977
  - **Rejection Rate**: <1% for most alphabet sizes
986
- - **Distribution**: Perfect uniform (mathematically proven)
978
+ - **Distribution**: Uniform distribution using rejection sampling
987
979
  - **Best For**: General-purpose applications, custom alphabets
988
980
 
989
981
  ### Real-World Performance
data/docs/_config.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  # Site settings
2
- title: OpaqueId Documentation
2
+ title: OpaqueId
3
3
  description: Generate cryptographically secure, collision-free opaque IDs for ActiveRecord models
4
4
  url: "https://nyaggah.github.io"
5
5
  baseurl: "/opaque_id"
@@ -88,6 +88,8 @@ kramdown:
88
88
  block:
89
89
  line_numbers: false
90
90
  start_line: 1
91
+ auto_id: true
92
+ table_of_contents: true
91
93
 
92
94
  # Custom head includes
93
95
  head_scripts:
@@ -104,23 +106,12 @@ nav_external_links_new_tab: true
104
106
  nav_footer: true
105
107
  nav_order: 1
106
108
 
107
- # Header and footer
108
- header_links:
109
- - title: "GitHub"
110
- url: "https://github.com/nyaggah/opaque_id"
111
- - title: "RubyGems"
112
- url: "https://rubygems.org/gems/opaque_id"
113
-
114
- # Auxiliary links (moved to sidebar top)
109
+ # Auxiliary links (appear at top right)
115
110
  aux_links:
116
- - title: "GitHub"
117
- url: "https://github.com/nyaggah/opaque_id"
118
- - title: "RubyGems"
119
- url: "https://rubygems.org/gems/opaque_id"
120
- - title: "Issues"
121
- url: "https://github.com/nyaggah/opaque_id/issues"
122
- - title: "Releases"
123
- url: "https://github.com/nyaggah/opaque_id/releases"
111
+ GitHub: https://github.com/nyaggah/opaque_id
112
+ RubyGems: https://rubygems.org/gems/opaque_id
113
+ Issues: https://github.com/nyaggah/opaque_id/issues
114
+ Releases: https://github.com/nyaggah/opaque_id/releases
124
115
 
125
116
  # Color scheme - use system theme with light fallback
126
117
  color_scheme: light
data/docs/algorithms.md CHANGED
@@ -8,7 +8,10 @@ permalink: /algorithms/
8
8
 
9
9
  # Algorithms
10
10
 
11
- OpaqueId uses sophisticated algorithms to generate cryptographically secure, collision-free opaque IDs. This guide explains the technical details behind the generation process, optimization strategies, and mathematical foundations.
11
+ OpaqueId builds on Ruby's built-in `SecureRandom` methods to generate cryptographically secure, collision-free opaque IDs. This guide explains the technical details behind the generation process, optimization strategies, and mathematical foundations.
12
+
13
+ - TOC
14
+ {:toc}
12
15
 
13
16
  ## Overview
14
17
 
@@ -42,10 +45,10 @@ end
42
45
 
43
46
  ### Key Features
44
47
 
45
- - **Bitwise Operations**: Uses `byte & 63` instead of `byte % 64` for faster computation
48
+ - **Bitwise Operations**: Uses `byte & 63` instead of `byte % 64` for efficient computation
46
49
  - **No Modulo Bias**: 64 is a power of 2, so bitwise AND provides uniform distribution
47
50
  - **Single Random Call**: One `SecureRandom.random_bytes(1)` call per character
48
- - **Maximum Performance**: Optimized for speed with 64-character alphabets
51
+ - **Performance Optimized**: Designed for speed with 64-character alphabets
49
52
 
50
53
  ### Mathematical Foundation
51
54
 
@@ -57,7 +60,7 @@ For a 64-character alphabet:
57
60
 
58
61
  ### Performance Characteristics
59
62
 
60
- - **Optimized for speed**: Uses bitwise operations for maximum performance
63
+ - **Optimized for speed**: Uses bitwise operations for efficient performance
61
64
  - **No rejection sampling**: All generated bytes are used efficiently
62
65
  - **Linear time complexity**: O(n) where n is the ID length
63
66
 
data/docs/alphabets.md CHANGED
@@ -10,6 +10,9 @@ permalink: /alphabets/
10
10
 
11
11
  OpaqueId provides flexible alphabet configuration for generating IDs with different character sets. This guide covers built-in alphabets, custom alphabet creation, and best practices for alphabet selection.
12
12
 
13
+ - TOC
14
+ {:toc}
15
+
13
16
  ## Built-in Alphabets
14
17
 
15
18
  OpaqueId comes with two pre-configured alphabets optimized for different use cases.
@@ -10,6 +10,9 @@ permalink: /api-reference/
10
10
 
11
11
  This document provides complete API documentation for OpaqueId, including all methods, classes, and configuration options.
12
12
 
13
+ - TOC
14
+ {:toc}
15
+
13
16
  ## Core Module: OpaqueId
14
17
 
15
18
  The main module for generating opaque IDs.
@@ -292,59 +292,12 @@ table {
292
292
  color: var(--nav-child-link-color);
293
293
  }
294
294
 
295
- // Auxiliary links styling (top of sidebar)
296
- .aux-nav {
297
- margin-bottom: 1.5rem;
298
- padding-bottom: 1rem;
299
- border-bottom: 1px solid var(--border-color-light);
300
-
301
- .aux-nav-list {
302
- list-style: none;
303
- margin: 0;
304
- padding: 0;
305
- display: flex;
306
- flex-wrap: wrap;
307
- gap: 0.5rem;
308
-
309
- .aux-nav-list-item {
310
- margin: 0;
311
-
312
- .aux-nav-list-link {
313
- display: inline-flex;
314
- align-items: center;
315
- padding: 0.375rem 0.75rem;
316
- font-size: 0.875rem;
317
- font-weight: 500;
318
- color: var(--aux-link-color);
319
- text-decoration: none;
320
- border: 1px solid var(--border-color);
321
- border-radius: 6px;
322
- background-color: transparent;
323
- transition: all 0.2s ease;
324
-
325
- &:hover {
326
- color: var(--aux-link-hover-color);
327
- border-color: var(--aux-link-hover-color);
328
- background-color: rgba(168, 85, 247, 0.05);
329
- text-decoration: none;
330
- }
331
-
332
- &:focus {
333
- outline: 2px solid var(--aux-link-hover-color);
334
- outline-offset: 2px;
335
- }
336
-
337
- // External link icon
338
- &[href^="http"]:not([href*="nyaggah.github.io"]) {
339
- &::after {
340
- content: "↗";
341
- margin-left: 0.25rem;
342
- font-size: 0.75rem;
343
- opacity: 0.7;
344
- }
345
- }
346
- }
347
- }
295
+ // Simple external links styling
296
+ .nav-list .nav-list-item .nav-list-link[href^="http"] {
297
+ color: var(--link-color);
298
+
299
+ &:hover {
300
+ color: var(--link-color-hover);
348
301
  }
349
302
  }
350
303
 
@@ -10,6 +10,9 @@ permalink: /configuration/
10
10
 
11
11
  OpaqueId provides extensive configuration options to customize ID generation for your specific needs. This guide covers all available configuration options with practical examples.
12
12
 
13
+ - TOC
14
+ {:toc}
15
+
13
16
  ## Model-Level Configuration
14
17
 
15
18
  Configure OpaqueId on a per-model basis using class-level settings.