digest-base32 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fa377043eb6395c1c5e4a291ead93e4fd4b6fc8d47f27e170062eea1681cfd34
4
+ data.tar.gz: 6c26617c5aac5d78856c95da27df1fb83fd5ae99c9fdebd801a1be2959c8b074
5
+ SHA512:
6
+ metadata.gz: 41eced816a3b48b60e3ebdb51d91d55cf34dd16fff7cba2eaffe5fb297f15126fac25849036f9b75614cc15911eaee443807155633167cc7c3e20fef766f3e3d
7
+ data.tar.gz: fffb14ed6166fa9b0a60e2c2ebd7a84de74474e32e69e50a67dba434794f3ec7fffe0806ac45f191566d6cdad3977139b0abb0587ed01e6388707e3816944e1d
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 James Cook
4
+ Copyright (c) 2020 Yauheni Dakuka
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ Digest::Base32
2
+ ==============
3
+
4
+ ![Travis Build](https://travis-ci.com/ydakuka/digest-base32.svg?branch=master)
5
+
6
+ Digest::Base32 is a Ruby native extension that wraps the base32 library found
7
+ in [tpmtotop](https://github.com/mjg59/tpmtotp/blob/master/base32.h)
8
+
9
+ Usage
10
+ -----
11
+
12
+ ```ruby
13
+ require 'digest/base32'
14
+
15
+ encoded = Digest::Base32.encode('My string')
16
+ decoded = Digest::Base32.decode(encoded)
17
+ ```
18
+
19
+ Benchmark
20
+ ---------
21
+
22
+ From Core i7 Macbook Pro (2014). Ruby 2.5.3
23
+ ```
24
+ user system total real
25
+ base32 pure ruby (encode) 1.348343 0.000489 1.348832 ( 1.349179)
26
+ base32 c extension (encode) 0.001638 0.000002 0.001640 ( 0.001629)
27
+ base32 pure ruby (decode) 1.334840 0.000574 1.335414 ( 1.335513)
28
+ base32 c extension (decode) 0.003613 0.000331 0.003944 ( 0.003933)
29
+ ```
30
+
31
+ Requirements
32
+ ------------
33
+
34
+ * Ruby 2.3+
35
+ * gcc/clang
36
+
37
+ Running the test suite
38
+ ----------------------
39
+
40
+ Run the test suite as follows:
41
+
42
+ ```
43
+ rake test
44
+ ```
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__).freeze
4
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib
5
+
6
+ require 'digest/base32/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'digest-base32'
10
+ spec.version = Digest::Base32::VERSION
11
+ spec.license = 'MIT'
12
+ spec.homepage = 'https://github.com/ydakuka/digest-base32'
13
+ spec.summary = 'Base32 Ruby C Extension'
14
+ spec.platform = Gem::Platform::RUBY
15
+
16
+ spec.authors = ['James Cook']
17
+
18
+ spec.description = <<-DESCRIPTION.split.join ' '
19
+ Ruby native extension for base32 encoding and decoding.
20
+ DESCRIPTION
21
+
22
+ spec.metadata = {
23
+ 'homepage_uri' => 'https://github.com/ydakuka/digest-base32',
24
+ 'source_code_uri' => 'https://github.com/ydakuka/digest-base32',
25
+ 'bug_tracker_uri' =>
26
+ 'https://github.com/ydakuka/digest-base32/issues',
27
+ }.freeze
28
+
29
+ spec.bindir = 'exe'
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.files = Dir[
33
+ 'README.md',
34
+ 'LICENSE',
35
+ 'Makefile',
36
+ 'digest-base32.gemspec',
37
+ 'ext/**/*.{c,h,rb}',
38
+ 'lib/**/*.{rb}',
39
+ ]
40
+
41
+ spec.executables = spec.files.grep %r{^exe/}, &File.method(:basename)
42
+
43
+ spec.extensions << 'ext/digest/base32/extconf.rb'
44
+
45
+ spec.add_development_dependency 'base32', '~> 0.3.2'
46
+ spec.add_development_dependency 'bundler', '~> 2.1'
47
+ spec.add_development_dependency 'pry', '~> 0.12'
48
+ spec.add_development_dependency 'rake', '~> 12.3'
49
+ spec.add_development_dependency 'rake-compiler', '~> 1.1'
50
+ spec.add_development_dependency 'rspec', '~> 3.9'
51
+ spec.add_development_dependency 'rubocop', '~> 0.80'
52
+ spec.add_development_dependency 'rubocop-performance', '~> 1.5'
53
+ end
@@ -0,0 +1,221 @@
1
+ /**
2
+ * base32 (de)coder implementation as specified by RFC4648.
3
+ *
4
+ * Copyright (c) 2010 Adrien Kunysz
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ **/
24
+
25
+ #include <assert.h> // assert()
26
+ #include <limits.h> // CHAR_BIT
27
+
28
+ #include "base32.h"
29
+
30
+ /**
31
+ * Let this be a sequence of plain data before encoding:
32
+ *
33
+ * 01234567 01234567 01234567 01234567 01234567
34
+ * +--------+--------+--------+--------+--------+
35
+ * |< 0 >< 1| >< 2 ><|.3 >< 4.|>< 5 ><.|6 >< 7 >|
36
+ * +--------+--------+--------+--------+--------+
37
+ *
38
+ * There are 5 octets of 8 bits each in each sequence.
39
+ * There are 8 blocks of 5 bits each in each sequence.
40
+ *
41
+ * You probably want to refer to that graph when reading the algorithms in this
42
+ * file. We use "octet" instead of "byte" intentionnaly as we really work with
43
+ * 8 bits quantities. This implementation will probably not work properly on
44
+ * systems that don't have exactly 8 bits per (unsigned) char.
45
+ **/
46
+
47
+ static size_t min(size_t x, size_t y)
48
+ {
49
+ return x < y ? x : y;
50
+ }
51
+
52
+ static const unsigned char PADDING_CHAR = '=';
53
+
54
+ /**
55
+ * Pad the given buffer with len padding characters.
56
+ */
57
+ static void pad(unsigned char *buf, int len)
58
+ {
59
+ for (int i = 0; i < len; i++)
60
+ buf[i] = PADDING_CHAR;
61
+ }
62
+
63
+ /**
64
+ * This convert a 5 bits value into a base32 character.
65
+ * Only the 5 least significant bits are used.
66
+ */
67
+ static unsigned char encode_char(unsigned char c)
68
+ {
69
+ static unsigned char base32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
70
+ return base32[c & 0x1F]; // 0001 1111
71
+ }
72
+
73
+ /**
74
+ * Decode given character into a 5 bits value.
75
+ * Returns -1 iff the argument given was an invalid base32 character
76
+ * or a padding character.
77
+ */
78
+ static int decode_char(unsigned char c)
79
+ {
80
+ char retval = -1;
81
+
82
+ if (c >= 'A' && c <= 'Z')
83
+ retval = c - 'A';
84
+ if (c >= '2' && c <= '7')
85
+ retval = c - '2' + 26;
86
+
87
+ assert(retval == -1 || ((retval & 0x1F) == retval));
88
+
89
+ return retval;
90
+ }
91
+
92
+ /**
93
+ * Given a block id between 0 and 7 inclusive, this will return the index of
94
+ * the octet in which this block starts. For example, given 3 it will return 1
95
+ * because block 3 starts in octet 1:
96
+ *
97
+ * +--------+--------+
98
+ * | ......<|.3 >....|
99
+ * +--------+--------+
100
+ * octet 1 | octet 2
101
+ */
102
+ static int get_octet(int block)
103
+ {
104
+ assert(block >= 0 && block < 8);
105
+ return (block*5) / 8;
106
+ }
107
+
108
+ /**
109
+ * Given a block id between 0 and 7 inclusive, this will return how many bits
110
+ * we can drop at the end of the octet in which this block starts.
111
+ * For example, given block 0 it will return 3 because there are 3 bits
112
+ * we don't care about at the end:
113
+ *
114
+ * +--------+-
115
+ * |< 0 >...|
116
+ * +--------+-
117
+ *
118
+ * Given block 1, it will return -2 because there
119
+ * are actually two bits missing to have a complete block:
120
+ *
121
+ * +--------+-
122
+ * |.....< 1|..
123
+ * +--------+-
124
+ **/
125
+ static int get_offset(int block)
126
+ {
127
+ assert(block >= 0 && block < 8);
128
+ return (8 - 5 - (5*block) % 8);
129
+ }
130
+
131
+ /**
132
+ * Like "b >> offset" but it will do the right thing with negative offset.
133
+ * We need this as bitwise shifting by a negative offset is undefined
134
+ * behavior.
135
+ */
136
+ static unsigned char shift_right(unsigned char byte, char offset)
137
+ {
138
+ if (offset > 0)
139
+ return byte >> offset;
140
+ else
141
+ return byte << -offset;
142
+ }
143
+
144
+ static unsigned char shift_left(unsigned char byte, char offset)
145
+ {
146
+ return shift_right(byte, - offset);
147
+ }
148
+
149
+ /**
150
+ * Encode a sequence. A sequence is no longer than 5 octets by definition.
151
+ * Thus passing a length greater than 5 to this function is an error. Encoding
152
+ * sequences shorter than 5 octets is supported and padding will be added to the
153
+ * output as per the specification.
154
+ */
155
+ static void encode_sequence(const unsigned char *plain, int len, unsigned char *coded)
156
+ {
157
+ assert(CHAR_BIT == 8); // not sure this would work otherwise
158
+ assert(len >= 0 && len <= 5);
159
+
160
+ for (int block = 0; block < 8; block++) {
161
+ int octet = get_octet(block); // figure out which octet this block starts in
162
+ int junk = get_offset(block); // how many bits do we drop from this octet?
163
+
164
+ if (octet >= len) { // we hit the end of the buffer
165
+ pad(&coded[block], 8 - block);
166
+ return;
167
+ }
168
+
169
+ unsigned char c = shift_right(plain[octet], junk); // first part
170
+
171
+ if (junk < 0 // is there a second part?
172
+ && octet < len - 1) // is there still something to read?
173
+ {
174
+ c |= shift_right(plain[octet+1], 8 + junk);
175
+ }
176
+ coded[block] = encode_char(c);
177
+ }
178
+ }
179
+
180
+ void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded)
181
+ {
182
+ // All the hard work is done in encode_sequence(),
183
+ // here we just need to feed it the data sequence by sequence.
184
+ for (size_t i = 0, j = 0; i < len; i += 5, j += 8) {
185
+ encode_sequence(&plain[i], (int)min(len - i, 5), &coded[j]);
186
+ }
187
+ }
188
+
189
+ static int decode_sequence(const unsigned char *coded, unsigned char *plain)
190
+ {
191
+ assert(CHAR_BIT == 8);
192
+ assert(coded && plain);
193
+
194
+ plain[0] = 0;
195
+ for (int block = 0; block < 8; block++) {
196
+ int offset = get_offset(block);
197
+ int octet = get_octet(block);
198
+
199
+ int c = decode_char(coded[block]);
200
+ if (c < 0) // invalid char, stop here
201
+ return octet;
202
+
203
+ plain[octet] |= shift_left(c, offset);
204
+ if (offset < 0) { // does this block overflows to next octet?
205
+ assert(octet < 4);
206
+ plain[octet+1] = shift_left(c, 8 + offset);
207
+ }
208
+ }
209
+ return 5;
210
+ }
211
+
212
+ size_t base32_decode(const unsigned char *coded, unsigned char *plain)
213
+ {
214
+ size_t written = 0;
215
+ for (size_t i = 0, j = 0; ; i += 8, j += 5) {
216
+ int n = decode_sequence(&coded[i], &plain[j]);
217
+ written += n;
218
+ if (n < 5)
219
+ return written;
220
+ }
221
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * base32 (de)coder implementation as specified by RFC4648.
3
+ *
4
+ * Copyright (c) 2010 Adrien Kunysz
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ **/
24
+
25
+ #ifndef __BASE32_H_
26
+ #define __BASE32_H_
27
+
28
+ #include <stddef.h> // size_t
29
+
30
+ /**
31
+ * Returns the length of the output buffer required to encode len bytes of
32
+ * data into base32. This is a macro to allow users to define buffer size at
33
+ * compilation time.
34
+ */
35
+ #define BASE32_LEN(len) (((len)/5)*8 + ((len) % 5 ? 8 : 0))
36
+
37
+ /**
38
+ * Returns the length of the output buffer required to decode a base32 string
39
+ * of len characters. Please note that len must be a multiple of 8 as per
40
+ * definition of a base32 string. This is a macro to allow users to define
41
+ * buffer size at compilation time.
42
+ */
43
+ #define UNBASE32_LEN(len) (((len)/8)*5)
44
+
45
+ /**
46
+ * Encode the data pointed to by plain into base32 and store the
47
+ * result at the address pointed to by coded. The "coded" argument
48
+ * must point to a location that has enough available space
49
+ * to store the whole coded string. The resulting string will only
50
+ * contain characters from the [A-Z2-7=] set. The "len" arguments
51
+ * define how many bytes will be read from the "plain" buffer.
52
+ **/
53
+ void base32_encode(const unsigned char *plain, size_t len, unsigned char *coded);
54
+
55
+ /**
56
+ * Decode the null terminated string pointed to by coded and write
57
+ * the decoded data into the location pointed to by plain. The
58
+ * "plain" argument must point to a location that has enough available
59
+ * space to store the whole decoded string.
60
+ * Returns the length of the decoded string. This may be less than
61
+ * expected due to padding. If an invalid base32 character is found
62
+ * in the coded string, decoding will stop at that point.
63
+ **/
64
+ size_t base32_decode(const unsigned char *coded, unsigned char *plain);
65
+
66
+ #endif
@@ -0,0 +1,64 @@
1
+ #include <stdlib.h>
2
+ #include <ruby.h>
3
+ #include <ruby/encoding.h>
4
+ #include "base32.h"
5
+ #include <ctype.h>
6
+
7
+ static VALUE mDigest;
8
+ static VALUE mDigest_cBase32;
9
+ static VALUE eDecodeError;
10
+
11
+ static VALUE
12
+ digest_base32_encode(int argc, VALUE* argv, VALUE self)
13
+ {
14
+ VALUE input;
15
+ const unsigned char* src;
16
+ size_t srclen;
17
+ rb_scan_args(argc, argv, "1", &input);
18
+
19
+ if (TYPE(input) != T_STRING) {
20
+ rb_raise(rb_eTypeError, "expected a String");
21
+ }
22
+
23
+ src = (unsigned char*) StringValuePtr(input);
24
+ srclen = BASE32_LEN(RSTRING_LEN(input));
25
+
26
+ unsigned char dest[srclen];
27
+ base32_encode(src, RSTRING_LEN(input), dest);
28
+
29
+ return rb_str_new((const char*) dest, srclen);
30
+ }
31
+
32
+ static VALUE
33
+ digest_base32_decode(int argc, VALUE *argv, VALUE self)
34
+ {
35
+ VALUE input;
36
+ const unsigned char* src;
37
+ size_t input_len, estimate_len;
38
+
39
+ rb_scan_args(argc, argv, "1", &input);
40
+
41
+ if (TYPE(input) != T_STRING) {
42
+ rb_raise(rb_eTypeError, "expected a String");
43
+ }
44
+
45
+ src = (unsigned char*) StringValuePtr(input);
46
+ input_len = RSTRING_LEN(input);
47
+ estimate_len = UNBASE32_LEN(input_len);
48
+ unsigned char out[estimate_len];
49
+
50
+ base32_decode(src, out);
51
+
52
+ return rb_str_new_cstr((const char*) out);
53
+ }
54
+
55
+ void
56
+ Init_base32() {
57
+ mDigest = rb_define_module("Digest");
58
+ mDigest_cBase32 = rb_define_class_under(mDigest, "Base32", rb_cObject);
59
+
60
+ eDecodeError = rb_define_class_under(mDigest_cBase32, "DecodeError", rb_eStandardError);
61
+
62
+ rb_define_module_function(mDigest_cBase32, "encode", digest_base32_encode, -1);
63
+ rb_define_module_function(mDigest_cBase32, "decode", digest_base32_decode, -1);
64
+ }
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+
5
+ dir_config('digest/base32')
6
+
7
+ raise 'Could not find base32.h' unless find_header 'base32.h', __dir__
8
+
9
+ create_makefile('digest/base32')
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Digest
4
+ class Base32
5
+ VERSION = '0.0.1'
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: digest-base32
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Cook
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-03-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base32
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.3.2
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.3.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '12.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '12.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake-compiler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.9'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.9'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.80'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.80'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-performance
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.5'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.5'
125
+ description: Ruby native extension for base32 encoding and decoding.
126
+ email:
127
+ executables: []
128
+ extensions:
129
+ - ext/digest/base32/extconf.rb
130
+ extra_rdoc_files: []
131
+ files:
132
+ - LICENSE
133
+ - README.md
134
+ - digest-base32.gemspec
135
+ - ext/digest/base32/base32.c
136
+ - ext/digest/base32/base32.h
137
+ - ext/digest/base32/digest-base32.c
138
+ - ext/digest/base32/extconf.rb
139
+ - lib/digest/base32/version.rb
140
+ homepage: https://github.com/ydakuka/digest-base32
141
+ licenses:
142
+ - MIT
143
+ metadata:
144
+ homepage_uri: https://github.com/ydakuka/digest-base32
145
+ source_code_uri: https://github.com/ydakuka/digest-base32
146
+ bug_tracker_uri: https://github.com/ydakuka/digest-base32/issues
147
+ post_install_message:
148
+ rdoc_options: []
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubygems_version: 3.0.3
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: Base32 Ruby C Extension
166
+ test_files: []