base58_id 1.0.0 → 1.1.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: 350af1c45ca377d67a9d8223e069a2fe4d7578ba2a1428f54fa0ed9dfc3935e0
4
- data.tar.gz: bb0a090804ba8890d5d3c1a851932dd137ff64985b806c01736c1b3c9b63fe0a
3
+ metadata.gz: 65f4480fda9f96d178cef620945be28ff9dbf552d7d52076af7f5bd240e7e430
4
+ data.tar.gz: 685d5c2bd0c49d6acbd961939efafcaea0a2e327cf9ee0fb377605b026a0e27e
5
5
  SHA512:
6
- metadata.gz: 39220e72e36409269d9d6d6dc74bf54a6aef3c40a45096f049190e3e89a0b68df150e6ab843deadb951b99c6e630981a29b05db18a757293845caeaea938a2b6
7
- data.tar.gz: 5450dc9d8a03b82716ba14c8bb9000654b80918200586b10c1ba1211626962d73fbb9a0f698ec8098e6c6951608373537cdb746790130034e7a816e87be4cca6
6
+ metadata.gz: fb7ab1847d946c426915cd79879f88928f68b9b9e509a3e9852b821feac65f1c7937bc58931bb469eb798cbdb887a4b6a9109693d449a1d38a65589e02435d06
7
+ data.tar.gz: e39086f6f0850df707f8075029326f71566190767a090316d22f3adcb94d5a6d8cfc7710c9f1a2ed7501b13c00b7577796067b745a4d3ab0e4843a9fb3e644bc
data/.rubocop.yml CHANGED
@@ -39,6 +39,9 @@ Style/TrailingCommaInArrayLiteral:
39
39
  Style/TrailingCommaInHashLiteral:
40
40
  Enabled: false
41
41
 
42
+ Naming/MethodParameterName:
43
+ Enabled: false
44
+
42
45
  RSpec/ExampleLength:
43
46
  Enabled: false
44
47
  RSpec/MultipleExpectations:
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Base58Id
2
2
 
3
- Convert an Integer ID or a UUID String to/from Base58 String
3
+ Convert Integer ID or UUID String to/from Base58 String; Generate random Base58 String
4
4
 
5
5
  ## Install
6
6
 
@@ -15,14 +15,14 @@ Or via `Gemfile` in your project:
15
15
  ```sh
16
16
  source 'https://rubygems.org'
17
17
 
18
- gem 'base58_id', '~> 1.0'
18
+ gem 'base58_id', '~> 1.1'
19
19
  ```
20
20
 
21
21
  Or build and install the gem locally:
22
22
 
23
23
  ```sh
24
24
  gem build base58_id.gemspec
25
- gem install base58_id-1.0.0.gem
25
+ gem install base58_id-1.1.0.gem
26
26
  ```
27
27
 
28
28
  Require it in your Ruby code and the `Base58Id` class will be available:
@@ -41,7 +41,9 @@ a b c d e f g h i j k m n o p q r s t u v w x y z
41
41
  1 2 3 4 5 6 7 8 9
42
42
  ```
43
43
 
44
- ## Example
44
+ ## Examples
45
+
46
+ ### Converting
45
47
 
46
48
  ```rb
47
49
  require 'base58_id'
@@ -82,12 +84,14 @@ Base58Id::UUID_PATTERN
82
84
  # => /\A(0x)?[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}\z/i
83
85
  ```
84
86
 
85
- ### Note
87
+ ### Notes about zero
86
88
 
87
89
  As it performs an integer conversion, Base58 leading zeros (represented by `A`)
88
90
  are ignored/lost:
89
91
 
90
92
  ```rb
93
+ require 'base58_id'
94
+
91
95
  Base58Id.base58_to_integer('A') == Base58Id.base58_to_integer('AAAAAA')
92
96
  # => true
93
97
 
@@ -102,6 +106,8 @@ Base58Id.integer_to_base58(Base58Id.base58_to_integer('AAAAAAqocqGYw9LEfu4WVujMz
102
106
  And an empty Base58 String also represents zero:
103
107
 
104
108
  ```rb
109
+ require 'base58_id'
110
+
105
111
  Base58Id.base58_to_integer('')
106
112
  # => 0
107
113
 
@@ -112,6 +118,66 @@ Base58Id.base58_to_integer('') == Base58Id.base58_to_integer('A')
112
118
  # => true
113
119
  ```
114
120
 
121
+ ### Generating random Base58 number strings from Integers
122
+
123
+ ```rb
124
+ require 'base58_id'
125
+
126
+ # Using the default range [0, 2^63 - 1]
127
+ Base58Id.random_number
128
+ # => "RvHTkxcYYJ4"
129
+
130
+ # With a custom max, i.e. [0, max)
131
+ Base58Id.random_number(100) # [0, 100)
132
+ # => "BW"
133
+
134
+ # With custom ranges
135
+ Base58Id.random_number(100..1_000) # [100, 1000]
136
+ # => "L2"
137
+ Base58Id.random_number(100...1_000) # [100, 1000)
138
+ # => "Qv"
139
+ ```
140
+
141
+ Under the hood, the implementation just passes the `max_or_range` argument to
142
+ `SecureRandom.random_number` and then the result to `Base58Id.integer_to_base58`:
143
+
144
+ ```rb
145
+ require 'securerandom'
146
+ require 'base58_id'
147
+
148
+ class Base58Id
149
+ # ...
150
+
151
+ DEFAULT_RANDOM_RANGE = 0..(2**63 - 1)
152
+
153
+ # ...
154
+
155
+ def self.random_number(max_or_range = nil)
156
+ max_or_range = DEFAULT_RANDOM_RANGE if max_or_range.nil?
157
+
158
+ integer_to_base58(SecureRandom.random_number(max_or_range))
159
+ end
160
+
161
+ def self.rand(*args)
162
+ random_number(*args)
163
+ end
164
+ end
165
+ ```
166
+
167
+ ### Generating random Base58 string digits
168
+
169
+ ```rb
170
+ require 'base58_id'
171
+
172
+ # Using the default number of random digits, 10
173
+ Base58Id.random_digits
174
+ # => "EWcSDcga66"
175
+
176
+ # With a custom number of random digits
177
+ Base58Id.random_digits(42)
178
+ # => "YJn8u1UhkS9vt3YrWFPTXzMjzqFze7v2nWUbcdmnrU"
179
+ ```
180
+
115
181
  ## Tests
116
182
 
117
183
  Run tests with:
data/base58_id.gemspec CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
6
6
  s.name = 'base58_id'
7
7
  s.version = Base58Id::VERSION
8
8
  s.license = 'MIT'
9
- s.summary = 'Convert an Integer ID or a UUID String to/from Base58 String'
9
+ s.summary = 'Convert Integer ID or UUID String to/from Base58 String; Generate random Base58 String'
10
10
  s.homepage = 'https://github.com/elias19r/base58_id'
11
11
  s.author = 'Elias Rodrigues'
12
12
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Base58Id
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
data/lib/base58_id.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'securerandom'
4
+
3
5
  class Base58Id
4
6
  # Based on Base64 URL-safe alphabet but with I, O, l, 0, -, _ removed.
5
7
  ALPHABET_58 = %w[
@@ -15,6 +17,9 @@ class Base58Id
15
17
  UUID_PATTERN = /\A(0x)?[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}\z/i.freeze
16
18
  UUID_BYTES_FORMAT = '%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x'
17
19
 
20
+ DEFAULT_RANDOM_RANGE = (0..((2**63) - 1)).freeze
21
+ DEFAULT_RANDOM_DIGITS = 10
22
+
18
23
  def self.integer_to_base58(integer)
19
24
  raise ArgumentError, 'argument must be an Integer' unless integer.is_a?(Integer)
20
25
  raise ArgumentError, 'argument must be greater than or equal to zero' if integer.negative?
@@ -70,4 +75,22 @@ class Base58Id
70
75
 
71
76
  value.match?(UUID_PATTERN)
72
77
  end
78
+
79
+ def self.random_number(max_or_range = nil)
80
+ max_or_range = DEFAULT_RANDOM_RANGE if max_or_range.nil?
81
+
82
+ integer_to_base58(SecureRandom.random_number(max_or_range))
83
+ end
84
+
85
+ def self.rand(*args)
86
+ random_number(*args)
87
+ end
88
+
89
+ def self.random_digits(n = nil)
90
+ n = DEFAULT_RANDOM_DIGITS if n.nil?
91
+
92
+ raise ArgumentError, 'argument must be an Integer' unless n.is_a?(Integer)
93
+
94
+ n.times.reduce('') { |str, _| str + ALPHABET_58[SecureRandom.random_number(58)] }
95
+ end
73
96
  end
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
  require 'base58_id'
5
5
 
6
6
  RSpec.describe Base58Id do
7
- it 'converts an Integer ID or a UUID String to/from Base58 String' do
7
+ it 'converts Integer ID or UUID String to/from Base58 String' do
8
8
  base58 = generate_base58
9
9
 
10
10
  expect(
@@ -366,6 +366,108 @@ RSpec.describe Base58Id do
366
366
  end
367
367
  end
368
368
 
369
+ describe '.random_number' do
370
+ context 'when max_or_range is not set or nil' do
371
+ it 'generates a random Base58 String using the default range' do
372
+ expected_default_random_range = 0..((2**63) - 1)
373
+
374
+ allow(SecureRandom).to receive(:random_number).with(expected_default_random_range).and_return(1000)
375
+
376
+ expect(described_class.random_number).to eq('TQ')
377
+ expect(described_class.random_number(nil)).to eq('TQ')
378
+
379
+ expect(SecureRandom).to have_received(:random_number).with(expected_default_random_range).twice
380
+ end
381
+ end
382
+
383
+ context 'when max_or_range is set and not nil' do
384
+ it 'generates a random Base58 String using the given range' do
385
+ max_or_range = 100
386
+
387
+ allow(SecureRandom).to receive(:random_number).and_return(99)
388
+
389
+ expect(described_class.random_number(max_or_range)).to eq('Bs')
390
+
391
+ expect(SecureRandom).to have_received(:random_number).with(max_or_range).once
392
+ end
393
+ end
394
+ end
395
+
396
+ describe '.rand as an alias to random_number' do
397
+ context 'when max_or_range is not set or nil' do
398
+ it 'generates a random Base58 String using the default range' do
399
+ expected_default_random_range = 0..((2**63) - 1)
400
+
401
+ allow(SecureRandom).to receive(:random_number).with(expected_default_random_range).and_return(1000)
402
+
403
+ expect(described_class.rand).to eq('TQ')
404
+ expect(described_class.rand(nil)).to eq('TQ')
405
+
406
+ expect(SecureRandom).to have_received(:random_number).with(expected_default_random_range).twice
407
+ end
408
+ end
409
+
410
+ context 'when max_or_range is set and not nil' do
411
+ it 'generates a random Base58 String using the given range' do
412
+ max_or_range = 100
413
+
414
+ allow(SecureRandom).to receive(:random_number).and_return(99)
415
+
416
+ expect(described_class.rand(max_or_range)).to eq('Bs')
417
+
418
+ expect(SecureRandom).to have_received(:random_number).with(max_or_range).once
419
+ end
420
+ end
421
+ end
422
+
423
+ describe '.random_digits' do
424
+ context 'when n is set to non-nil but not an Integer' do
425
+ it 'raises an ArgumentError' do
426
+ non_integer = Object.new
427
+
428
+ expect do
429
+ described_class.random_digits(non_integer)
430
+ end.to raise_error(ArgumentError, 'argument must be an Integer')
431
+ end
432
+ end
433
+
434
+ context 'when n is not set or nil' do
435
+ it 'generates a random string of 10 Base58 digits' do
436
+ string = described_class.random_digits
437
+
438
+ expect(string.size).to eq(10)
439
+ expect(string.count("^#{base58_chars.join}")).to eq(0)
440
+
441
+ string = described_class.random_digits(nil)
442
+
443
+ expect(string.size).to eq(10)
444
+ expect(string.count("^#{base58_chars.join}")).to eq(0)
445
+ end
446
+ end
447
+
448
+ context 'when n is zero or a negative Integer' do
449
+ it 'returns an empty string' do
450
+ string = described_class.random_digits(0)
451
+
452
+ expect(string).to eq('')
453
+
454
+ string = described_class.random_digits(generate_negative_integer)
455
+
456
+ expect(string).to eq('')
457
+ end
458
+ end
459
+
460
+ context 'when n is a positive Integer' do
461
+ it 'generates a random string of n Base58 digits' do
462
+ n = SecureRandom.random_number(1..256)
463
+ string = described_class.random_digits(n)
464
+
465
+ expect(string.size).to eq(n)
466
+ expect(string.count("^#{base58_chars.join}")).to eq(0)
467
+ end
468
+ end
469
+ end
470
+
369
471
  def generate_uuid
370
472
  SecureRandom.uuid
371
473
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: base58_id
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elias Rodrigues
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-30 00:00:00.000000000 Z
11
+ date: 2022-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -128,7 +128,7 @@ homepage: https://github.com/elias19r/base58_id
128
128
  licenses:
129
129
  - MIT
130
130
  metadata:
131
- source_code_uri: https://github.com/elias19r/base58_id/tree/v1.0.0
131
+ source_code_uri: https://github.com/elias19r/base58_id/tree/v1.1.0
132
132
  rubygems_mfa_required: 'true'
133
133
  post_install_message:
134
134
  rdoc_options: []
@@ -145,8 +145,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0'
147
147
  requirements: []
148
- rubygems_version: 3.1.6
148
+ rubygems_version: 3.1.4
149
149
  signing_key:
150
150
  specification_version: 4
151
- summary: Convert an Integer ID or a UUID String to/from Base58 String
151
+ summary: Convert Integer ID or UUID String to/from Base58 String; Generate random
152
+ Base58 String
152
153
  test_files: []