base58_id 1.0.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 +7 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +49 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +129 -0
- data/base58_id.gemspec +37 -0
- data/lib/base58_id/version.rb +5 -0
- data/lib/base58_id.rb +73 -0
- data/spec/base58_id_spec.rb +494 -0
- data/spec/spec_helper.rb +8 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 350af1c45ca377d67a9d8223e069a2fe4d7578ba2a1428f54fa0ed9dfc3935e0
|
4
|
+
data.tar.gz: bb0a090804ba8890d5d3c1a851932dd137ff64985b806c01736c1b3c9b63fe0a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 39220e72e36409269d9d6d6dc74bf54a6aef3c40a45096f049190e3e89a0b68df150e6ab843deadb951b99c6e630981a29b05db18a757293845caeaea938a2b6
|
7
|
+
data.tar.gz: 5450dc9d8a03b82716ba14c8bb9000654b80918200586b10c1ba1211626962d73fbb9a0f698ec8098e6c6951608373537cdb746790130034e7a816e87be4cca6
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-performance
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
TargetRubyVersion: 2.7
|
7
|
+
NewCops: enable
|
8
|
+
|
9
|
+
Metrics/BlockLength:
|
10
|
+
Exclude:
|
11
|
+
- 'spec/**/*.rb'
|
12
|
+
Metrics/MethodLength:
|
13
|
+
Exclude:
|
14
|
+
- 'spec/**/*.rb'
|
15
|
+
|
16
|
+
Layout/LineLength:
|
17
|
+
Max: 120
|
18
|
+
Layout/HashAlignment:
|
19
|
+
Enabled: false
|
20
|
+
Layout/SpaceInsideArrayPercentLiteral:
|
21
|
+
Enabled: false
|
22
|
+
Layout/ArrayAlignment:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Style/Documentation:
|
26
|
+
Enabled: false
|
27
|
+
Style/WhileUntilModifier:
|
28
|
+
Enabled: false
|
29
|
+
Style/WordArray:
|
30
|
+
Enabled: false
|
31
|
+
Style/SymbolArray:
|
32
|
+
Enabled: false
|
33
|
+
Style/NumericLiterals:
|
34
|
+
Enabled: false
|
35
|
+
Style/StringLiterals:
|
36
|
+
Enabled: false
|
37
|
+
Style/TrailingCommaInArrayLiteral:
|
38
|
+
Enabled: false
|
39
|
+
Style/TrailingCommaInHashLiteral:
|
40
|
+
Enabled: false
|
41
|
+
|
42
|
+
RSpec/ExampleLength:
|
43
|
+
Enabled: false
|
44
|
+
RSpec/MultipleExpectations:
|
45
|
+
Enabled: false
|
46
|
+
RSpec/NestedGroups:
|
47
|
+
Enabled: false
|
48
|
+
RSpec/LetBeforeExamples:
|
49
|
+
Enabled: false
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2022 Elias Rodrigues
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# Base58Id
|
2
|
+
|
3
|
+
Convert an Integer ID or a UUID String to/from Base58 String
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
Install it from rubygems.org in your terminal:
|
8
|
+
|
9
|
+
```sh
|
10
|
+
gem install base58_id
|
11
|
+
```
|
12
|
+
|
13
|
+
Or via `Gemfile` in your project:
|
14
|
+
|
15
|
+
```sh
|
16
|
+
source 'https://rubygems.org'
|
17
|
+
|
18
|
+
gem 'base58_id', '~> 1.0'
|
19
|
+
```
|
20
|
+
|
21
|
+
Or build and install the gem locally:
|
22
|
+
|
23
|
+
```sh
|
24
|
+
gem build base58_id.gemspec
|
25
|
+
gem install base58_id-1.0.0.gem
|
26
|
+
```
|
27
|
+
|
28
|
+
Require it in your Ruby code and the `Base58Id` class will be available:
|
29
|
+
|
30
|
+
```rb
|
31
|
+
require 'base58_id'
|
32
|
+
```
|
33
|
+
|
34
|
+
## Alphabet
|
35
|
+
|
36
|
+
It is based on Base64 URL-safe alphabet but with `I`, `O`, `l`, `0`, `-`, `_` removed:
|
37
|
+
|
38
|
+
```
|
39
|
+
A B C D E F G H J K L M N P Q R S T U V W X Y Z
|
40
|
+
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
|
+
1 2 3 4 5 6 7 8 9
|
42
|
+
```
|
43
|
+
|
44
|
+
## Example
|
45
|
+
|
46
|
+
```rb
|
47
|
+
require 'base58_id'
|
48
|
+
|
49
|
+
Base58Id.uuid_to_base58('058917af-0d2e-4755-b0bd-25b02b249824')
|
50
|
+
# => "qocqGYw9LEfu4WVujMzJv"
|
51
|
+
|
52
|
+
Base58Id.base58_to_uuid('qocqGYw9LEfu4WVujMzJv')
|
53
|
+
# => "058917af-0d2e-4755-b0bd-25b02b249824"
|
54
|
+
|
55
|
+
Base58Id.uuid_to_integer('058917af-0d2e-4755-b0bd-25b02b249824')
|
56
|
+
# => 7357965012972427318415208560898381860
|
57
|
+
|
58
|
+
Base58Id.integer_to_uuid(7357965012972427318415208560898381860)
|
59
|
+
# => "058917af-0d2e-4755-b0bd-25b02b249824"
|
60
|
+
|
61
|
+
Base58Id.base58_to_integer('qocqGYw9LEfu4WVujMzJv')
|
62
|
+
# => 7357965012972427318415208560898381860
|
63
|
+
|
64
|
+
Base58Id.integer_to_base58(7357965012972427318415208560898381860)
|
65
|
+
# => "qocqGYw9LEfu4WVujMzJv"
|
66
|
+
|
67
|
+
Base58Id.valid_base58?('qocqGYw9LEfu4WVujMzJv')
|
68
|
+
# => true
|
69
|
+
|
70
|
+
Base58Id.valid_base58?('IOl0-_')
|
71
|
+
# => false
|
72
|
+
|
73
|
+
# It accepts UUID String in many formats:
|
74
|
+
[
|
75
|
+
'058917af0d2e4755b0bd25b02b249824',
|
76
|
+
'058917AF0D2E4755B0BD25B02B249824',
|
77
|
+
'0x058917af0d2e4755b0bd25b02b249824',
|
78
|
+
].map { |uuid| Base58Id.valid_uuid?(uuid) }
|
79
|
+
# => [true, true, true]
|
80
|
+
|
81
|
+
Base58Id::UUID_PATTERN
|
82
|
+
# => /\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
|
+
```
|
84
|
+
|
85
|
+
### Note
|
86
|
+
|
87
|
+
As it performs an integer conversion, Base58 leading zeros (represented by `A`)
|
88
|
+
are ignored/lost:
|
89
|
+
|
90
|
+
```rb
|
91
|
+
Base58Id.base58_to_integer('A') == Base58Id.base58_to_integer('AAAAAA')
|
92
|
+
# => true
|
93
|
+
|
94
|
+
Base58Id.base58_to_integer('AAAAAAqocqGYw9LEfu4WVujMzJv') ==
|
95
|
+
Base58Id.base58_to_integer('qocqGYw9LEfu4WVujMzJv')
|
96
|
+
# => true
|
97
|
+
|
98
|
+
Base58Id.integer_to_base58(Base58Id.base58_to_integer('AAAAAAqocqGYw9LEfu4WVujMzJv'))
|
99
|
+
# => "qocqGYw9LEfu4WVujMzJv"
|
100
|
+
```
|
101
|
+
|
102
|
+
And an empty Base58 String also represents zero:
|
103
|
+
|
104
|
+
```rb
|
105
|
+
Base58Id.base58_to_integer('')
|
106
|
+
# => 0
|
107
|
+
|
108
|
+
Base58Id.base58_to_uuid('')
|
109
|
+
# => "00000000-0000-0000-0000-000000000000"
|
110
|
+
|
111
|
+
Base58Id.base58_to_integer('') == Base58Id.base58_to_integer('A')
|
112
|
+
# => true
|
113
|
+
```
|
114
|
+
|
115
|
+
## Tests
|
116
|
+
|
117
|
+
Run tests with:
|
118
|
+
|
119
|
+
```sh
|
120
|
+
bundle exec rspec
|
121
|
+
```
|
122
|
+
|
123
|
+
## Linter
|
124
|
+
|
125
|
+
Check your code with:
|
126
|
+
|
127
|
+
```sh
|
128
|
+
bundle exec rubocop
|
129
|
+
```
|
data/base58_id.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/base58_id/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'base58_id'
|
7
|
+
s.version = Base58Id::VERSION
|
8
|
+
s.license = 'MIT'
|
9
|
+
s.summary = 'Convert an Integer ID or a UUID String to/from Base58 String'
|
10
|
+
s.homepage = 'https://github.com/elias19r/base58_id'
|
11
|
+
s.author = 'Elias Rodrigues'
|
12
|
+
|
13
|
+
s.files = Dir[
|
14
|
+
'lib/**/*',
|
15
|
+
'spec/**/*',
|
16
|
+
'.gitignore',
|
17
|
+
'.rubocop.yml',
|
18
|
+
'Gemfile',
|
19
|
+
'LICENSE',
|
20
|
+
'README.md',
|
21
|
+
'base58_id.gemspec'
|
22
|
+
]
|
23
|
+
|
24
|
+
s.required_ruby_version = '>= 2.7'
|
25
|
+
s.metadata = {
|
26
|
+
'source_code_uri' => "https://github.com/elias19r/base58_id/tree/v#{Base58Id::VERSION}",
|
27
|
+
'rubygems_mfa_required' => 'true'
|
28
|
+
}
|
29
|
+
|
30
|
+
s.add_development_dependency 'bundler', '~> 2.1'
|
31
|
+
s.add_development_dependency 'pry-byebug', '~> 3.9'
|
32
|
+
s.add_development_dependency 'rspec', '~> 3.11'
|
33
|
+
s.add_development_dependency 'rubocop', '~> 1.31'
|
34
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.14'
|
35
|
+
s.add_development_dependency 'rubocop-rspec', '~> 2.11'
|
36
|
+
s.add_development_dependency 'simplecov', '~> 0.21.0'
|
37
|
+
end
|
data/lib/base58_id.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Base58Id
|
4
|
+
# Based on Base64 URL-safe alphabet but with I, O, l, 0, -, _ removed.
|
5
|
+
ALPHABET_58 = %w[
|
6
|
+
A B C D E F G H J K L M N P Q R S T U V W X Y Z
|
7
|
+
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
|
8
|
+
1 2 3 4 5 6 7 8 9
|
9
|
+
].freeze
|
10
|
+
|
11
|
+
ALPHABET_58_INVERT = ALPHABET_58.each_with_index.to_h
|
12
|
+
ALPHABET_58_CHARS = ALPHABET_58.join
|
13
|
+
CARET_ALPHABET_58_CHARS = "^#{ALPHABET_58_CHARS}"
|
14
|
+
|
15
|
+
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
|
+
UUID_BYTES_FORMAT = '%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x'
|
17
|
+
|
18
|
+
def self.integer_to_base58(integer)
|
19
|
+
raise ArgumentError, 'argument must be an Integer' unless integer.is_a?(Integer)
|
20
|
+
raise ArgumentError, 'argument must be greater than or equal to zero' if integer.negative?
|
21
|
+
|
22
|
+
integer.digits(58).reduce('') { |str, digit| ALPHABET_58[digit] + str }
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.base58_to_integer(base58)
|
26
|
+
raise ArgumentError, 'argument must be a valid Base58 String' unless valid_base58?(base58)
|
27
|
+
|
28
|
+
base58.chars.reduce(0) { |integer, digit| (integer * 58) + ALPHABET_58_INVERT[digit] }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.uuid_to_base58(uuid)
|
32
|
+
raise ArgumentError, 'argument must be a valid UUID String' unless valid_uuid?(uuid)
|
33
|
+
|
34
|
+
integer_to_base58(uuid_to_integer(uuid))
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.base58_to_uuid(base58)
|
38
|
+
integer_to_uuid(base58_to_integer(base58))
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.uuid_to_integer(uuid)
|
42
|
+
raise ArgumentError, 'argument must be a valid UUID String' unless valid_uuid?(uuid)
|
43
|
+
|
44
|
+
uuid.delete('-').to_i(16)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.integer_to_uuid(integer)
|
48
|
+
raise ArgumentError, 'argument must be an Integer' unless integer.is_a?(Integer)
|
49
|
+
raise ArgumentError, 'argument must be greater than or equal to zero' if integer.negative?
|
50
|
+
|
51
|
+
bytes_array = integer.digits(256)
|
52
|
+
|
53
|
+
raise ArgumentError, 'argument size must not require more than 16 bytes' if bytes_array.size > 16
|
54
|
+
|
55
|
+
while bytes_array.size < 16
|
56
|
+
bytes_array.push(0)
|
57
|
+
end
|
58
|
+
|
59
|
+
UUID_BYTES_FORMAT % bytes_array.reverse
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.valid_base58?(value)
|
63
|
+
raise ArgumentError, 'argument must be a String' unless value.is_a?(String)
|
64
|
+
|
65
|
+
value.count(CARET_ALPHABET_58_CHARS).zero?
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.valid_uuid?(value)
|
69
|
+
raise ArgumentError, 'argument must be a String' unless value.is_a?(String)
|
70
|
+
|
71
|
+
value.match?(UUID_PATTERN)
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,494 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'base58_id'
|
5
|
+
|
6
|
+
RSpec.describe Base58Id do
|
7
|
+
it 'converts an Integer ID or a UUID String to/from Base58 String' do
|
8
|
+
base58 = generate_base58
|
9
|
+
|
10
|
+
expect(
|
11
|
+
described_class.integer_to_base58(
|
12
|
+
described_class.base58_to_integer(base58)
|
13
|
+
)
|
14
|
+
).to eq(base58)
|
15
|
+
|
16
|
+
expect(
|
17
|
+
described_class.uuid_to_base58(
|
18
|
+
described_class.base58_to_uuid(base58)
|
19
|
+
)
|
20
|
+
).to eq(base58)
|
21
|
+
|
22
|
+
base58_with_leading_zeros = "AAAAAAAA#{base58}"
|
23
|
+
|
24
|
+
expect(
|
25
|
+
described_class.integer_to_base58(
|
26
|
+
described_class.base58_to_integer(base58_with_leading_zeros)
|
27
|
+
)
|
28
|
+
).to eq(base58)
|
29
|
+
|
30
|
+
expect(
|
31
|
+
described_class.uuid_to_base58(
|
32
|
+
described_class.base58_to_uuid(base58_with_leading_zeros)
|
33
|
+
)
|
34
|
+
).to eq(base58)
|
35
|
+
|
36
|
+
base58_empty = ''
|
37
|
+
|
38
|
+
expect(
|
39
|
+
described_class.integer_to_base58(
|
40
|
+
described_class.base58_to_integer(base58_empty)
|
41
|
+
)
|
42
|
+
).to eq('A')
|
43
|
+
|
44
|
+
expect(
|
45
|
+
described_class.uuid_to_base58(
|
46
|
+
described_class.base58_to_uuid(base58_empty)
|
47
|
+
)
|
48
|
+
).to eq('A')
|
49
|
+
|
50
|
+
integer = generate_non_negative_integer
|
51
|
+
|
52
|
+
expect(
|
53
|
+
described_class.base58_to_integer(
|
54
|
+
described_class.integer_to_base58(integer)
|
55
|
+
)
|
56
|
+
).to eq(integer)
|
57
|
+
|
58
|
+
expect(
|
59
|
+
described_class.uuid_to_integer(
|
60
|
+
described_class.integer_to_uuid(integer)
|
61
|
+
)
|
62
|
+
).to eq(integer)
|
63
|
+
|
64
|
+
uuid = generate_uuid
|
65
|
+
|
66
|
+
expect(
|
67
|
+
described_class.base58_to_uuid(
|
68
|
+
described_class.uuid_to_base58(uuid)
|
69
|
+
)
|
70
|
+
).to eq(uuid)
|
71
|
+
|
72
|
+
expect(
|
73
|
+
described_class.integer_to_uuid(
|
74
|
+
described_class.uuid_to_integer(uuid)
|
75
|
+
)
|
76
|
+
).to eq(uuid)
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '.integer_to_base58' do
|
80
|
+
context 'when argument is not an Integer' do
|
81
|
+
it 'raises an ArgumentError' do
|
82
|
+
non_integer = Object.new
|
83
|
+
|
84
|
+
expect do
|
85
|
+
described_class.integer_to_base58(non_integer)
|
86
|
+
end.to raise_error(ArgumentError, 'argument must be an Integer')
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when argument is an Integer but negative' do
|
91
|
+
it 'raises an ArgumentError' do
|
92
|
+
negative_integer = generate_negative_integer
|
93
|
+
|
94
|
+
expect do
|
95
|
+
described_class.integer_to_base58(negative_integer)
|
96
|
+
end.to raise_error(ArgumentError, 'argument must be greater than or equal to zero')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when argument is a non-negative Integer' do
|
101
|
+
it 'formats unsigned integer as Base58 String' do
|
102
|
+
integer = generate_non_negative_integer
|
103
|
+
|
104
|
+
expect(described_class.integer_to_base58(integer).count("^#{base58_chars.join}")).to eq(0)
|
105
|
+
|
106
|
+
some_test_cases.each do |test_case|
|
107
|
+
expect(described_class.integer_to_base58(test_case[:integer])).to eq(test_case[:base58])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '.base58_to_integer' do
|
114
|
+
context 'when value is not a valid Base58 String' do
|
115
|
+
it 'raises an ArgumentError' do
|
116
|
+
non_string = Object.new
|
117
|
+
|
118
|
+
expect do
|
119
|
+
described_class.base58_to_integer(non_string)
|
120
|
+
end.to raise_error(ArgumentError, 'argument must be a String')
|
121
|
+
|
122
|
+
non_base58_chars.each do |non_base58|
|
123
|
+
expect do
|
124
|
+
described_class.base58_to_integer(non_base58)
|
125
|
+
end.to raise_error(ArgumentError, 'argument must be a valid Base58 String')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when value is a valid Base58 String' do
|
131
|
+
it 'returns the corresponding Integer' do
|
132
|
+
big_base58 = generate_big_base58
|
133
|
+
|
134
|
+
expect(described_class.base58_to_integer(big_base58)).to be_an(Integer)
|
135
|
+
|
136
|
+
base58_empty = ''
|
137
|
+
|
138
|
+
expect(described_class.base58_to_integer(base58_empty)).to eq(0)
|
139
|
+
|
140
|
+
some_test_cases.each do |test_case|
|
141
|
+
expect(described_class.base58_to_integer(test_case[:base58])).to eq(test_case[:integer])
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '.uuid_to_base58' do
|
148
|
+
context 'when argument is not a valid UUID String' do
|
149
|
+
it 'raises an ArgumentError' do
|
150
|
+
non_string = Object.new
|
151
|
+
|
152
|
+
expect do
|
153
|
+
described_class.uuid_to_base58(non_string)
|
154
|
+
end.to raise_error(ArgumentError, 'argument must be a String')
|
155
|
+
|
156
|
+
non_uuid = '123'
|
157
|
+
|
158
|
+
expect do
|
159
|
+
described_class.uuid_to_base58(non_uuid)
|
160
|
+
end.to raise_error(ArgumentError, 'argument must be a valid UUID String')
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'when argument is a valid UUID String' do
|
165
|
+
it 'returns the corresponding Base58' do
|
166
|
+
uuid = generate_uuid
|
167
|
+
|
168
|
+
expect(described_class.uuid_to_base58(uuid).count("^#{base58_chars.join}")).to eq(0)
|
169
|
+
|
170
|
+
some_test_cases.each do |test_case|
|
171
|
+
expect(described_class.uuid_to_base58(test_case[:uuid])).to eq(test_case[:base58])
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe '.base58_to_uuid' do
|
178
|
+
context 'when value is not a valid Base58 String' do
|
179
|
+
it 'raises an ArgumentError' do
|
180
|
+
non_string = Object.new
|
181
|
+
|
182
|
+
expect do
|
183
|
+
described_class.base58_to_uuid(non_string)
|
184
|
+
end.to raise_error(ArgumentError, 'argument must be a String')
|
185
|
+
|
186
|
+
non_base58_chars.each do |non_base58|
|
187
|
+
expect do
|
188
|
+
described_class.base58_to_uuid(non_base58)
|
189
|
+
end.to raise_error(ArgumentError, 'argument must be a valid Base58 String')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'when value is a valid Base58 String but numeric value requires more than 16 bytes' do
|
195
|
+
it 'raises an ArgumentError' do
|
196
|
+
big_base58 = generate_big_base58
|
197
|
+
|
198
|
+
expect do
|
199
|
+
described_class.base58_to_uuid(big_base58)
|
200
|
+
end.to raise_error(ArgumentError, 'argument size must not require more than 16 bytes')
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'when value is a valid Base58 String and numeric value does not require more than 16 bytes' do
|
205
|
+
it 'returns the corresponding UUID String' do
|
206
|
+
base58 = generate_base58
|
207
|
+
|
208
|
+
expect(described_class.base58_to_uuid(base58))
|
209
|
+
.to match(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/)
|
210
|
+
|
211
|
+
base58_empty = ''
|
212
|
+
|
213
|
+
expect(described_class.base58_to_uuid(base58_empty)).to eq('00000000-0000-0000-0000-000000000000')
|
214
|
+
|
215
|
+
some_test_cases.each do |test_case|
|
216
|
+
expect(described_class.base58_to_uuid(test_case[:base58])).to eq(test_case[:uuid])
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe '.uuid_to_integer' do
|
223
|
+
context 'when argument is not a valid UUID String' do
|
224
|
+
it 'raises an ArgumentError' do
|
225
|
+
non_string = Object.new
|
226
|
+
|
227
|
+
expect do
|
228
|
+
described_class.uuid_to_integer(non_string)
|
229
|
+
end.to raise_error(ArgumentError, 'argument must be a String')
|
230
|
+
|
231
|
+
non_uuid = '123'
|
232
|
+
|
233
|
+
expect do
|
234
|
+
described_class.uuid_to_integer(non_uuid)
|
235
|
+
end.to raise_error(ArgumentError, 'argument must be a valid UUID String')
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'when argument is a valid UUID String' do
|
240
|
+
it 'returns the corresponding Integer' do
|
241
|
+
uuid = generate_uuid
|
242
|
+
|
243
|
+
expect(described_class.uuid_to_integer(uuid)).to be_an(Integer)
|
244
|
+
|
245
|
+
some_test_cases.each do |test_case|
|
246
|
+
expect(described_class.uuid_to_integer(test_case[:uuid])).to eq(test_case[:integer])
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '.integer_to_uuid' do
|
253
|
+
context 'when argument is not an Integer' do
|
254
|
+
it 'raises an ArgumentError' do
|
255
|
+
non_integer = Object.new
|
256
|
+
|
257
|
+
expect do
|
258
|
+
described_class.integer_to_uuid(non_integer)
|
259
|
+
end.to raise_error(ArgumentError, 'argument must be an Integer')
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
context 'when argument is an Integer but negative' do
|
264
|
+
it 'raises an ArgumentError' do
|
265
|
+
negative_integer = generate_negative_integer
|
266
|
+
|
267
|
+
expect do
|
268
|
+
described_class.integer_to_uuid(negative_integer)
|
269
|
+
end.to raise_error(ArgumentError, 'argument must be greater than or equal to zero')
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context 'when argument is a non-negative Integer but requires more than 16 bytes' do
|
274
|
+
it 'raises an ArgumentError' do
|
275
|
+
big_integer = generate_big_integer
|
276
|
+
|
277
|
+
expect do
|
278
|
+
described_class.integer_to_uuid(big_integer)
|
279
|
+
end.to raise_error(ArgumentError, 'argument size must not require more than 16 bytes')
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
context 'when argument is a non-negative Integer and does not require more than 16 bytes' do
|
284
|
+
it 'formats 128-bit unsigned integer as UUID String' do
|
285
|
+
uuid = generate_uuid
|
286
|
+
integer = uuid.delete('-').to_i(16)
|
287
|
+
|
288
|
+
expect(described_class.integer_to_uuid(integer)).to eq(uuid)
|
289
|
+
|
290
|
+
some_test_cases.each do |test_case|
|
291
|
+
expect(described_class.integer_to_uuid(test_case[:integer])).to eq(test_case[:uuid])
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
describe '.valid_base58?' do
|
298
|
+
context 'when value is not a String' do
|
299
|
+
it 'raises an ArgumentError' do
|
300
|
+
value = Object.new
|
301
|
+
|
302
|
+
expect do
|
303
|
+
described_class.valid_base58?(value)
|
304
|
+
end.to raise_error(ArgumentError, 'argument must be a String')
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
context 'when value is a String but contains chars not present in the Base58 alphabet' do
|
309
|
+
it 'returns false' do
|
310
|
+
non_base58_chars.each do |value|
|
311
|
+
expect(described_class.valid_base58?(value)).to be(false)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context 'when value is a String and contains only chars present in the Base58 alphabet' do
|
317
|
+
it 'returns true' do
|
318
|
+
base58_chars.each do |value|
|
319
|
+
expect(described_class.valid_base58?(value)).to be(true)
|
320
|
+
end
|
321
|
+
|
322
|
+
value = ''
|
323
|
+
|
324
|
+
expect(described_class.valid_base58?(value)).to be(true)
|
325
|
+
|
326
|
+
value = generate_big_base58
|
327
|
+
|
328
|
+
expect(described_class.valid_base58?(value)).to be(true)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
describe '.valid_uuid?' do
|
334
|
+
context 'when value is not a String' do
|
335
|
+
it 'raises an ArgumentError' do
|
336
|
+
value = Object.new
|
337
|
+
|
338
|
+
expect do
|
339
|
+
described_class.valid_uuid?(value)
|
340
|
+
end.to raise_error(ArgumentError, 'argument must be a String')
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context 'when value is a String but does not match the UUID pattern' do
|
345
|
+
it 'returns false' do
|
346
|
+
value = '123'
|
347
|
+
|
348
|
+
expect(described_class.valid_uuid?(value)).to be(false)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
context 'when value is a String and matches the UUID pattern' do
|
353
|
+
it 'returns true' do
|
354
|
+
value = generate_uuid
|
355
|
+
|
356
|
+
expect(described_class.valid_uuid?(value)).to be(true)
|
357
|
+
expect(described_class.valid_uuid?(value.delete('-'))).to be(true)
|
358
|
+
expect(described_class.valid_uuid?("0x#{value.delete('-')}")).to be(true)
|
359
|
+
expect(described_class.valid_uuid?("0X#{value.delete('-')}")).to be(true)
|
360
|
+
|
361
|
+
expect(described_class.valid_uuid?(value.upcase)).to be(true)
|
362
|
+
expect(described_class.valid_uuid?(value.upcase.delete('-'))).to be(true)
|
363
|
+
expect(described_class.valid_uuid?("0x#{value.upcase.delete('-')}")).to be(true)
|
364
|
+
expect(described_class.valid_uuid?("0X#{value.upcase.delete('-')}")).to be(true)
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def generate_uuid
|
370
|
+
SecureRandom.uuid
|
371
|
+
end
|
372
|
+
|
373
|
+
def generate_negative_integer
|
374
|
+
rand((-2**63)..-1)
|
375
|
+
end
|
376
|
+
|
377
|
+
def generate_non_negative_integer
|
378
|
+
rand(0..((2**63) - 1))
|
379
|
+
end
|
380
|
+
|
381
|
+
def generate_big_integer
|
382
|
+
rand((2**128)..(2**144))
|
383
|
+
end
|
384
|
+
|
385
|
+
def generate_base58
|
386
|
+
generate_non_zero_base58_digit + base58_chars.sample(19).join
|
387
|
+
end
|
388
|
+
|
389
|
+
def generate_big_base58
|
390
|
+
generate_non_zero_base58_digit + base58_chars.sample(24).join
|
391
|
+
end
|
392
|
+
|
393
|
+
def generate_non_zero_base58_digit
|
394
|
+
base58_chars[1..].sample
|
395
|
+
end
|
396
|
+
|
397
|
+
let(:base58_chars) do
|
398
|
+
%w[
|
399
|
+
A B C D E F G H J K L M N P Q R S T U V W X Y Z
|
400
|
+
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
|
401
|
+
1 2 3 4 5 6 7 8 9
|
402
|
+
]
|
403
|
+
end
|
404
|
+
|
405
|
+
let(:non_base58_chars) do
|
406
|
+
(' '..'~').to_a - base58_chars
|
407
|
+
end
|
408
|
+
|
409
|
+
let(:some_test_cases) do
|
410
|
+
[
|
411
|
+
{ integer: 0, base58: 'A', uuid: '00000000-0000-0000-0000-000000000000' },
|
412
|
+
{ integer: 1, base58: 'B', uuid: '00000000-0000-0000-0000-000000000001' },
|
413
|
+
{ integer: 2, base58: 'C', uuid: '00000000-0000-0000-0000-000000000002' },
|
414
|
+
{ integer: 3, base58: 'D', uuid: '00000000-0000-0000-0000-000000000003' },
|
415
|
+
{ integer: 4, base58: 'E', uuid: '00000000-0000-0000-0000-000000000004' },
|
416
|
+
{ integer: 5, base58: 'F', uuid: '00000000-0000-0000-0000-000000000005' },
|
417
|
+
{ integer: 6, base58: 'G', uuid: '00000000-0000-0000-0000-000000000006' },
|
418
|
+
{ integer: 7, base58: 'H', uuid: '00000000-0000-0000-0000-000000000007' },
|
419
|
+
{ integer: 8, base58: 'J', uuid: '00000000-0000-0000-0000-000000000008' },
|
420
|
+
{ integer: 9, base58: 'K', uuid: '00000000-0000-0000-0000-000000000009' },
|
421
|
+
{ integer: 10, base58: 'L', uuid: '00000000-0000-0000-0000-00000000000a' },
|
422
|
+
{ integer: 11, base58: 'M', uuid: '00000000-0000-0000-0000-00000000000b' },
|
423
|
+
{ integer: 12, base58: 'N', uuid: '00000000-0000-0000-0000-00000000000c' },
|
424
|
+
{ integer: 13, base58: 'P', uuid: '00000000-0000-0000-0000-00000000000d' },
|
425
|
+
{ integer: 14, base58: 'Q', uuid: '00000000-0000-0000-0000-00000000000e' },
|
426
|
+
{ integer: 15, base58: 'R', uuid: '00000000-0000-0000-0000-00000000000f' },
|
427
|
+
{ integer: 16, base58: 'S', uuid: '00000000-0000-0000-0000-000000000010' },
|
428
|
+
{ integer: 17, base58: 'T', uuid: '00000000-0000-0000-0000-000000000011' },
|
429
|
+
{ integer: 18, base58: 'U', uuid: '00000000-0000-0000-0000-000000000012' },
|
430
|
+
{ integer: 19, base58: 'V', uuid: '00000000-0000-0000-0000-000000000013' },
|
431
|
+
{ integer: 20, base58: 'W', uuid: '00000000-0000-0000-0000-000000000014' },
|
432
|
+
{ integer: 21, base58: 'X', uuid: '00000000-0000-0000-0000-000000000015' },
|
433
|
+
{ integer: 22, base58: 'Y', uuid: '00000000-0000-0000-0000-000000000016' },
|
434
|
+
{ integer: 23, base58: 'Z', uuid: '00000000-0000-0000-0000-000000000017' },
|
435
|
+
{ integer: 24, base58: 'a', uuid: '00000000-0000-0000-0000-000000000018' },
|
436
|
+
{ integer: 25, base58: 'b', uuid: '00000000-0000-0000-0000-000000000019' },
|
437
|
+
{ integer: 26, base58: 'c', uuid: '00000000-0000-0000-0000-00000000001a' },
|
438
|
+
{ integer: 27, base58: 'd', uuid: '00000000-0000-0000-0000-00000000001b' },
|
439
|
+
{ integer: 28, base58: 'e', uuid: '00000000-0000-0000-0000-00000000001c' },
|
440
|
+
{ integer: 29, base58: 'f', uuid: '00000000-0000-0000-0000-00000000001d' },
|
441
|
+
{ integer: 30, base58: 'g', uuid: '00000000-0000-0000-0000-00000000001e' },
|
442
|
+
{ integer: 31, base58: 'h', uuid: '00000000-0000-0000-0000-00000000001f' },
|
443
|
+
{ integer: 32, base58: 'i', uuid: '00000000-0000-0000-0000-000000000020' },
|
444
|
+
{ integer: 33, base58: 'j', uuid: '00000000-0000-0000-0000-000000000021' },
|
445
|
+
{ integer: 34, base58: 'k', uuid: '00000000-0000-0000-0000-000000000022' },
|
446
|
+
{ integer: 35, base58: 'm', uuid: '00000000-0000-0000-0000-000000000023' },
|
447
|
+
{ integer: 36, base58: 'n', uuid: '00000000-0000-0000-0000-000000000024' },
|
448
|
+
{ integer: 37, base58: 'o', uuid: '00000000-0000-0000-0000-000000000025' },
|
449
|
+
{ integer: 38, base58: 'p', uuid: '00000000-0000-0000-0000-000000000026' },
|
450
|
+
{ integer: 39, base58: 'q', uuid: '00000000-0000-0000-0000-000000000027' },
|
451
|
+
{ integer: 40, base58: 'r', uuid: '00000000-0000-0000-0000-000000000028' },
|
452
|
+
{ integer: 41, base58: 's', uuid: '00000000-0000-0000-0000-000000000029' },
|
453
|
+
{ integer: 42, base58: 't', uuid: '00000000-0000-0000-0000-00000000002a' },
|
454
|
+
{ integer: 43, base58: 'u', uuid: '00000000-0000-0000-0000-00000000002b' },
|
455
|
+
{ integer: 44, base58: 'v', uuid: '00000000-0000-0000-0000-00000000002c' },
|
456
|
+
{ integer: 45, base58: 'w', uuid: '00000000-0000-0000-0000-00000000002d' },
|
457
|
+
{ integer: 46, base58: 'x', uuid: '00000000-0000-0000-0000-00000000002e' },
|
458
|
+
{ integer: 47, base58: 'y', uuid: '00000000-0000-0000-0000-00000000002f' },
|
459
|
+
{ integer: 48, base58: 'z', uuid: '00000000-0000-0000-0000-000000000030' },
|
460
|
+
{ integer: 49, base58: '1', uuid: '00000000-0000-0000-0000-000000000031' },
|
461
|
+
{ integer: 50, base58: '2', uuid: '00000000-0000-0000-0000-000000000032' },
|
462
|
+
{ integer: 51, base58: '3', uuid: '00000000-0000-0000-0000-000000000033' },
|
463
|
+
{ integer: 52, base58: '4', uuid: '00000000-0000-0000-0000-000000000034' },
|
464
|
+
{ integer: 53, base58: '5', uuid: '00000000-0000-0000-0000-000000000035' },
|
465
|
+
{ integer: 54, base58: '6', uuid: '00000000-0000-0000-0000-000000000036' },
|
466
|
+
{ integer: 55, base58: '7', uuid: '00000000-0000-0000-0000-000000000037' },
|
467
|
+
{ integer: 56, base58: '8', uuid: '00000000-0000-0000-0000-000000000038' },
|
468
|
+
{ integer: 57, base58: '9', uuid: '00000000-0000-0000-0000-000000000039' },
|
469
|
+
{ integer: 58, base58: 'BA', uuid: '00000000-0000-0000-0000-00000000003a' },
|
470
|
+
|
471
|
+
{ integer: 58 * 2, base58: 'CA', uuid: '00000000-0000-0000-0000-000000000074' },
|
472
|
+
{ integer: 58 * 3, base58: 'DA', uuid: '00000000-0000-0000-0000-0000000000ae' },
|
473
|
+
{ integer: 58 * 10, base58: 'LA', uuid: '00000000-0000-0000-0000-000000000244' },
|
474
|
+
{ integer: 58 * 20, base58: 'WA', uuid: '00000000-0000-0000-0000-000000000488' },
|
475
|
+
{ integer: 58 * 58, base58: 'BAA', uuid: '00000000-0000-0000-0000-000000000d24' },
|
476
|
+
|
477
|
+
{ integer: 231, base58: 'D9', uuid: '00000000-0000-0000-0000-0000000000e7' },
|
478
|
+
{ integer: 232, base58: 'EA', uuid: '00000000-0000-0000-0000-0000000000e8' },
|
479
|
+
{ integer: 255, base58: 'EZ', uuid: '00000000-0000-0000-0000-0000000000ff' },
|
480
|
+
{ integer: 256, base58: 'Ea', uuid: '00000000-0000-0000-0000-000000000100' },
|
481
|
+
{ integer: 280, base58: 'Ez', uuid: '00000000-0000-0000-0000-000000000118' },
|
482
|
+
{ integer: 281, base58: 'E1', uuid: '00000000-0000-0000-0000-000000000119' },
|
483
|
+
{ integer: 289, base58: 'E9', uuid: '00000000-0000-0000-0000-000000000121' },
|
484
|
+
{ integer: 290, base58: 'FA', uuid: '00000000-0000-0000-0000-000000000122' },
|
485
|
+
|
486
|
+
{ integer: (58**10) - 1, base58: '9999999999', uuid: '00000000-0000-0000-05fa-8624c7fba3ff' },
|
487
|
+
{ integer: 58**10, base58: 'BAAAAAAAAAA', uuid: '00000000-0000-0000-05fa-8624c7fba400' },
|
488
|
+
{ integer: 58**20, base58: 'BAAAAAAAAAAAAAAAAAAAA', uuid: '0023be67-b5f0-f288-9aaf-505301100000' },
|
489
|
+
|
490
|
+
{ integer: (2**128) - 2, base58: 'hmep7uZkFTa9zuEuQB3XV4', uuid: 'ffffffff-ffff-ffff-ffff-fffffffffffe' },
|
491
|
+
{ integer: (2**128) - 1, base58: 'hmep7uZkFTa9zuEuQB3XV5', uuid: 'ffffffff-ffff-ffff-ffff-ffffffffffff' },
|
492
|
+
]
|
493
|
+
end
|
494
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: base58_id
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Elias Rodrigues
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry-byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.11'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.11'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.31'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.31'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-performance
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.14'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.14'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.11'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.11'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.21.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.21.0
|
111
|
+
description:
|
112
|
+
email:
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- ".gitignore"
|
118
|
+
- ".rubocop.yml"
|
119
|
+
- Gemfile
|
120
|
+
- LICENSE
|
121
|
+
- README.md
|
122
|
+
- base58_id.gemspec
|
123
|
+
- lib/base58_id.rb
|
124
|
+
- lib/base58_id/version.rb
|
125
|
+
- spec/base58_id_spec.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
homepage: https://github.com/elias19r/base58_id
|
128
|
+
licenses:
|
129
|
+
- MIT
|
130
|
+
metadata:
|
131
|
+
source_code_uri: https://github.com/elias19r/base58_id/tree/v1.0.0
|
132
|
+
rubygems_mfa_required: 'true'
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '2.7'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubygems_version: 3.1.6
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Convert an Integer ID or a UUID String to/from Base58 String
|
152
|
+
test_files: []
|