base58_id 1.0.0 → 1.1.0

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: 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: []