base58_id 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|