base32-alphabets 1.0.0

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
+ SHA1:
3
+ metadata.gz: 172119bb357b29e94a3d86c76da19e2351f38339
4
+ data.tar.gz: 68d93fd3b370c85e7a81255f4824310693039ff9
5
+ SHA512:
6
+ metadata.gz: 06504a90143c2c945641fa15aaea86f547efc7d8fe5d6db677963132d4e890b6b8377c7dd91fc3b4f66583593a3fabe38295d95c423085b215cc9861c9201c3a
7
+ data.tar.gz: 106070cdcbb6a18f038059d6a2838ac00f29ebf4ef8e7a96ff577e66cd883fb4a4ce11260b5001c50e1b6ecd717e0f6837db428e3c9e7a3747f17ecdb733c2e7
data/HISTORY.md ADDED
@@ -0,0 +1,3 @@
1
+ ### 0.0.1 / 2018-03-25
2
+
3
+ * Everything is new. First release
data/LICENSE.md ADDED
@@ -0,0 +1,116 @@
1
+ CC0 1.0 Universal
2
+
3
+ Statement of Purpose
4
+
5
+ The laws of most jurisdictions throughout the world automatically confer
6
+ exclusive Copyright and Related Rights (defined below) upon the creator and
7
+ subsequent owner(s) (each and all, an "owner") of an original work of
8
+ authorship and/or a database (each, a "Work").
9
+
10
+ Certain owners wish to permanently relinquish those rights to a Work for the
11
+ purpose of contributing to a commons of creative, cultural and scientific
12
+ works ("Commons") that the public can reliably and without fear of later
13
+ claims of infringement build upon, modify, incorporate in other works, reuse
14
+ and redistribute as freely as possible in any form whatsoever and for any
15
+ purposes, including without limitation commercial purposes. These owners may
16
+ contribute to the Commons to promote the ideal of a free culture and the
17
+ further production of creative, cultural and scientific works, or to gain
18
+ reputation or greater distribution for their Work in part through the use and
19
+ efforts of others.
20
+
21
+ For these and/or other purposes and motivations, and without any expectation
22
+ of additional consideration or compensation, the person associating CC0 with a
23
+ Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24
+ and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25
+ and publicly distribute the Work under its terms, with knowledge of his or her
26
+ Copyright and Related Rights in the Work and the meaning and intended legal
27
+ effect of CC0 on those rights.
28
+
29
+ 1. Copyright and Related Rights. A Work made available under CC0 may be
30
+ protected by copyright and related or neighboring rights ("Copyright and
31
+ Related Rights"). Copyright and Related Rights include, but are not limited
32
+ to, the following:
33
+
34
+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
35
+ and translate a Work;
36
+
37
+ ii. moral rights retained by the original author(s) and/or performer(s);
38
+
39
+ iii. publicity and privacy rights pertaining to a person's image or likeness
40
+ depicted in a Work;
41
+
42
+ iv. rights protecting against unfair competition in regards to a Work,
43
+ subject to the limitations in paragraph 4(a), below;
44
+
45
+ v. rights protecting the extraction, dissemination, use and reuse of data in
46
+ a Work;
47
+
48
+ vi. database rights (such as those arising under Directive 96/9/EC of the
49
+ European Parliament and of the Council of 11 March 1996 on the legal
50
+ protection of databases, and under any national implementation thereof,
51
+ including any amended or successor version of such directive); and
52
+
53
+ vii. other similar, equivalent or corresponding rights throughout the world
54
+ based on applicable law or treaty, and any national implementations thereof.
55
+
56
+ 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57
+ applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58
+ unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59
+ and Related Rights and associated claims and causes of action, whether now
60
+ known or unknown (including existing as well as future claims and causes of
61
+ action), in the Work (i) in all territories worldwide, (ii) for the maximum
62
+ duration provided by applicable law or treaty (including future time
63
+ extensions), (iii) in any current or future medium and for any number of
64
+ copies, and (iv) for any purpose whatsoever, including without limitation
65
+ commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66
+ the Waiver for the benefit of each member of the public at large and to the
67
+ detriment of Affirmer's heirs and successors, fully intending that such Waiver
68
+ shall not be subject to revocation, rescission, cancellation, termination, or
69
+ any other legal or equitable action to disrupt the quiet enjoyment of the Work
70
+ by the public as contemplated by Affirmer's express Statement of Purpose.
71
+
72
+ 3. Public License Fallback. Should any part of the Waiver for any reason be
73
+ judged legally invalid or ineffective under applicable law, then the Waiver
74
+ shall be preserved to the maximum extent permitted taking into account
75
+ Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76
+ is so judged Affirmer hereby grants to each affected person a royalty-free,
77
+ non transferable, non sublicensable, non exclusive, irrevocable and
78
+ unconditional license to exercise Affirmer's Copyright and Related Rights in
79
+ the Work (i) in all territories worldwide, (ii) for the maximum duration
80
+ provided by applicable law or treaty (including future time extensions), (iii)
81
+ in any current or future medium and for any number of copies, and (iv) for any
82
+ purpose whatsoever, including without limitation commercial, advertising or
83
+ promotional purposes (the "License"). The License shall be deemed effective as
84
+ of the date CC0 was applied by Affirmer to the Work. Should any part of the
85
+ License for any reason be judged legally invalid or ineffective under
86
+ applicable law, such partial invalidity or ineffectiveness shall not
87
+ invalidate the remainder of the License, and in such case Affirmer hereby
88
+ affirms that he or she will not (i) exercise any of his or her remaining
89
+ Copyright and Related Rights in the Work or (ii) assert any associated claims
90
+ and causes of action with respect to the Work, in either case contrary to
91
+ Affirmer's express Statement of Purpose.
92
+
93
+ 4. Limitations and Disclaimers.
94
+
95
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
96
+ surrendered, licensed or otherwise affected by this document.
97
+
98
+ b. Affirmer offers the Work as-is and makes no representations or warranties
99
+ of any kind concerning the Work, express, implied, statutory or otherwise,
100
+ including without limitation warranties of title, merchantability, fitness
101
+ for a particular purpose, non infringement, or the absence of latent or
102
+ other defects, accuracy, or the present or absence of errors, whether or not
103
+ discoverable, all to the greatest extent permissible under applicable law.
104
+
105
+ c. Affirmer disclaims responsibility for clearing rights of other persons
106
+ that may apply to the Work or any use thereof, including without limitation
107
+ any person's Copyright and Related Rights in the Work. Further, Affirmer
108
+ disclaims responsibility for obtaining any necessary consents, permissions
109
+ or other rights required for any use of the Work.
110
+
111
+ d. Affirmer understands and acknowledges that Creative Commons is not a
112
+ party to this document and has no duty or obligation with respect to this
113
+ CC0 or use of the Work.
114
+
115
+ For more information, please see
116
+ <http://creativecommons.org/publicdomain/zero/1.0/>
data/Manifest.txt ADDED
@@ -0,0 +1,15 @@
1
+ HISTORY.md
2
+ LICENSE.md
3
+ Manifest.txt
4
+ README.md
5
+ Rakefile
6
+ lib/base32-alphabets.rb
7
+ lib/base32-alphabets/base.rb
8
+ lib/base32-alphabets/base32.rb
9
+ lib/base32-alphabets/crockford.rb
10
+ lib/base32-alphabets/electrologica.rb
11
+ lib/base32-alphabets/kai.rb
12
+ lib/base32-alphabets/version.rb
13
+ test/helper.rb
14
+ test/test_base32.rb
15
+ test/test_base32_crockford.rb
data/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # Base32 Encoding / Decoding - 5-Bit Notations / Alphabets - Kai / Crockford / Electrologica
2
+
3
+
4
+ Encode / decode numbers in 5-bit groups (2^5=32)
5
+ with Kai, Crockford or Electrologica notation / alphabet
6
+
7
+
8
+ * home :: [github.com/cryptocopycats/base32-alphabets](https://github.com/cryptocopycats/base32-alphabets)
9
+ * bugs :: [github.com/cryptocopycats/base32-alphabets/issues](https://github.com/cryptocopycats/base32-alphabets/issues)
10
+ * gem :: [rubygems.org/gems/base32-alphabets](https://rubygems.org/gems/base32-alphabets)
11
+ * rdoc :: [rubydoc.info/gems/base32-alphabets](http://rubydoc.info/gems/base32-alphabets)
12
+
13
+
14
+
15
+
16
+ [Kai](#kai) •
17
+ [Crockford](#crockford) •
18
+ [Electrologica](#electrologica)
19
+
20
+
21
+
22
+
23
+ ## Kai
24
+
25
+ The kai notation / alphabet (`123456789abcdefghijkmnopqrstuvwx`)
26
+
27
+ Note: Following base56 - the digit-0 and the letter-l
28
+ are NOT used in the kai alphabet / notation.
29
+
30
+ ### Kai (Base32) Notation
31
+
32
+ |Kai |Binary |Num|Kai |Binary |Num|Kai |Binary |Num|Kai |Binary |Num|
33
+ |------:|------:|--:|------:|------:|--:|------:|------:|--:|------:|------:|--:|
34
+ | **1** | 00000 | 00 | **9** | 01000 | 08 | **h** | 10000 |16 | **q** | 11000 |24 |
35
+ | **2** | 00001 | 01 | **a** | 01001 | 09 | **i** | 10001 |17 | **r** | 11001 |25 |
36
+ | **3** | 00010 | 02 | **b** | 01010 | 10 | **j** | 10010 |18 | **s** | 11010 |26 |
37
+ | **4** | 00011 | 03 | **c** | 01011 | 11 | **k** | 10011 |19 | **t** | 11011 |27 |
38
+ | **5** | 00100 | 04 | **d** | 01100 | 12 | **m** | 10100 |20 | **u** | 11100 |28 |
39
+ | **6** | 00101 | 05 | **e** | 01101 | 13 | **n** | 10101 |21 | **v** | 11101 |29 |
40
+ | **7** | 00110 | 06 | **f** | 01110 | 14 | **o** | 10110 |22 | **w** | 11110 |30 |
41
+ | **8** | 00111 | 07 | **g** | 01111 | 15 | **p** | 10111 |23 | **x** | 11111 |31 |
42
+
43
+ Note: The digit-0 and the letter-l are NOT used in kai.
44
+
45
+
46
+ ### Usage - Encode / Decode
47
+
48
+ ``` ruby
49
+ require 'base32-alphabets'
50
+
51
+
52
+ binary = 0b0000000000000000010010100101001010010011000111001110010000001000010111000001010010111101110011100000000101001010000000110001100010000100011010100000110010000000100011000110000000101001010010100110001100010100101000110100101000010010100101011011100111001110 # binary
53
+ hex = 0x00004a52931ce4085c14bdce014a0318846a0c808c60294a6314a34a_1295_b9ce # hex
54
+
55
+ pp binary == hex
56
+ # => true
57
+
58
+ str = "aaaa 7885 22f2 agff 1661 7755 e979 2441 6667 7664 a9aa cfff".gsub( ' ', '' )
59
+
60
+ str2 = Kai.encode( hex ) ## (binary) number to text
61
+ pp str
62
+ # => "aaaa788522f2agff16617755e979244166677664a9aacfff"
63
+ pp str2
64
+ # => "aaaa788522f2agff16617755e979244166677664a9aacfff"
65
+ pp str == str2
66
+ # => true
67
+ pp Kai.fmt( str2 )
68
+ # => "aaaa 7885 22f2 agff 1661 7755 e979 2441 6667 7664 a9aa cfff"
69
+
70
+ hex2 = Kai.decode( str2 ) ## text to (binary) number
71
+ pp hex
72
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
73
+ pp hex2
74
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
75
+ pp hex == hex2
76
+ # => true
77
+ ```
78
+
79
+ or
80
+
81
+
82
+ ``` ruby
83
+ Base32.format = :kai
84
+
85
+ str = Base32.encode( hex ) ## (binary) number to text
86
+ pp str
87
+ # => "aaaa788522f2agff16617755e979244166677664a9aacfff"
88
+ pp Base32.fmt( str )
89
+ # => "aaaa 7885 22f2 agff 1661 7755 e979 2441 6667 7664 a9aa cfff"
90
+ pp = Base32.decode( str ) ## text to (binary) number
91
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
92
+ ```
93
+
94
+
95
+ ### Why Kai?
96
+
97
+ The Kai notation / alphabet is named in honor of Kai Turner
98
+ who first deciphered the CryptoKitties 256-bit genes in 5-bit groups - thanks!
99
+ See [The CryptoKitties Genome Project: On Dominance, Inheritance and Mutation](https://medium.com/@kaigani/the-cryptokitties-genome-project-on-dominance-inheritance-and-mutation-b73059dcd0a4), January 2018.
100
+
101
+
102
+
103
+
104
+
105
+
106
+ ## Crockford
107
+
108
+ The crockford notation / alphabet (`0123456789abcdefghjkmnpqrstvwxyz`)
109
+
110
+ Note: The Crockford Base32 symbol set is a superset of the Base16 (hexadecimal) symbol set
111
+ and starts counting at zero (0).
112
+
113
+
114
+ ### Crockford (Base32) Notation
115
+
116
+ |Base32 |Binary |Num|Base32 |Binary |Num|Base32 |Binary |Num|Base32 |Binary |Num|
117
+ |------:|------:|--:|------:|------:|--:|------:|------:|--:|------:|------:|--:|
118
+ | **0** | 00000 | 00 | **8** | 01000 | 08 | **g** | 10000 |16 | **r** | 11000 |24 |
119
+ | **1** | 00001 | 01 | **9** | 01001 | 09 | **h** | 10001 |17 | **s** | 11001 |25 |
120
+ | **2** | 00010 | 02 | **a** | 01010 | 10 | **j** | 10010 |18 | **t** | 11010 |26 |
121
+ | **3** | 00011 | 03 | **b** | 01011 | 11 | **k** | 10011 |19 | **v** | 11011 |27 |
122
+ | **4** | 00100 | 04 | **c** | 01100 | 12 | **m** | 10100 |20 | **w** | 11100 |28 |
123
+ | **5** | 00101 | 05 | **d** | 01101 | 13 | **n** | 10101 |21 | **x** | 11101 |29 |
124
+ | **6** | 00110 | 06 | **e** | 01110 | 14 | **p** | 10110 |22 | **y** | 11110 |30 |
125
+ | **7** | 00111 | 07 | **f** | 01111 | 15 | **q** | 10111 |23 | **z** | 11111 |31 |
126
+
127
+ Note: 4 of the 26 letters are excluded: I L O U.
128
+
129
+ - I Can be confused with 1
130
+ - L Can be confused with 1
131
+ - O Can be confused with 0
132
+ - U Accidental obscenity
133
+
134
+
135
+
136
+ ### Usage - Encode / Decode
137
+
138
+ ``` ruby
139
+ require 'base32-alphabets'
140
+
141
+
142
+ binary = 0b0000000000000000010010100101001010010011000111001110010000001000010111000001010010111101110011100000000101001010000000110001100010000100011010100000110010000000100011000110000000101001010010100110001100010100101000110100101000010010100101011011100111001110 # binary
143
+ hex = 0x00004a52931ce4085c14bdce014a0318846a0c808c60294a6314a34a_1295_b9ce # hex
144
+
145
+ pp binary == hex
146
+ # => true
147
+
148
+ str = "9999 6774 11e1 9fee 0550 6644 d868 1330 5556 6553 9899 beee".gsub( ' ', '' )
149
+
150
+ str2 = Crockford.encode( hex ) ## (binary) number to text
151
+ pp str2
152
+ # => "9999677411e19fee05506644d8681330555665539899beee"
153
+ pp str == str2
154
+ # => true
155
+ pp Crockford.fmt( str2 )
156
+ # => "9999 6774 11e1 9fee 0550 6644 d868 1330 5556 6553 9899 beee"
157
+
158
+ hex2 = Crockford.decode( str2 ) ## text to (binary) number
159
+ pp hex
160
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
161
+ pp hex2
162
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
163
+ pp hex == hex2
164
+ # => true
165
+ ```
166
+
167
+ or
168
+
169
+
170
+ ``` ruby
171
+ Base32.format = :crockford
172
+
173
+ str = Base32.encode( hex ) ## (binary) number to text
174
+ pp str
175
+ # => "9999677411e19fee05506644d8681330555665539899beee"
176
+ pp Base32.fmt( str )
177
+ # => "9999 6774 11e1 9fee 0550 6644 d868 1330 5556 6553 9899 beee"
178
+ pp = Base32.decode( str ) ## text to (binary) number
179
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
180
+ ```
181
+
182
+
183
+
184
+ ## Electrologica
185
+
186
+ The electrologica notation / alphabet (
187
+ `00 01 02 03 04 05 06 07`
188
+ `08 09 10 11 12 13 14 15`
189
+ `16 17 18 19 20 21 22 23`
190
+ `24 25 26 27 28 29 30 31`)
191
+
192
+
193
+ ### Electrologica (Base32) Notation
194
+
195
+ |Base32 |Binary |Num|Base32 |Binary |Num|Base32 |Binary |Num|Base32 |Binary |Num|
196
+ |------:|------:|--:|------:|------:|--:|------:|------:|--:|------:|------:|--:|
197
+ | **00** | 00000 | 00 | **08** | 01000 | 08 | **16** | 10000 |16 | **24** | 11000 |24 |
198
+ | **01** | 00001 | 01 | **09** | 01001 | 09 | **17** | 10001 |17 | **25** | 11001 |25 |
199
+ | **02** | 00010 | 02 | **10** | 01010 | 10 | **18** | 10010 |18 | **26** | 11010 |26 |
200
+ | **03** | 00011 | 03 | **11** | 01011 | 11 | **19** | 10011 |19 | **27** | 11011 |27 |
201
+ | **04** | 00100 | 04 | **12** | 01100 | 12 | **20** | 10100 |20 | **28** | 11100 |28 |
202
+ | **05** | 00101 | 05 | **13** | 01101 | 13 | **21** | 10101 |21 | **29** | 11101 |29 |
203
+ | **06** | 00110 | 06 | **14** | 01110 | 14 | **22** | 10110 |22 | **30** | 11110 |30 |
204
+ | **07** | 00111 | 07 | **15** | 01111 | 15 | **23** | 10111 |23 | **31** | 11111 |31 |
205
+
206
+
207
+
208
+ ### Usage - Encode / Decode
209
+
210
+ ``` ruby
211
+ require 'base32-alphabets'
212
+
213
+
214
+ binary = 0b0000000000000000010010100101001010010011000111001110010000001000010111000001010010111101110011100000000101001010000000110001100010000100011010100000110010000000100011000110000000101001010010100110001100010100101000110100101000010010100101011011100111001110 # binary
215
+ hex = 0x00004a52931ce4085c14bdce014a0318846a0c808c60294a6314a34a_1295_b9ce # hex
216
+
217
+ pp binary == hex
218
+ # => true
219
+
220
+ str = "09-09-09-09 06-07-07-04 01-01-14-01 09-15-14-14 00-05-05-00 06-06-04-04 13-08-06-08 01-03-03-00 05-05-05-06 06-05-05-03 09-08-09-09 11-14-14-14".gsub( ' ', '-' )
221
+
222
+ str2 = Electrologica.encode( hex ) ## (binary) number to text
223
+ pp str2
224
+ # => "09-09-09-09-06-07-07-04-01-01-14-01-09-15-14-14-00-05-05-00-06-06-04-04-13-08-06-08-01-03-03-00-05-05-05-06-06-05-05-03-09-08-09-09-11-14-14-14"
225
+ pp str == str2
226
+ # => true
227
+ pp Electrologica.fmt( str2 )
228
+ # => "09-09-09-09 06-07-07-04 01-01-14-01 09-15-14-14 00-05-05-00 06-06-04-04 13-08-06-08 01-03-03-00 05-05-05-06 06-05-05-03 09-08-09-09 11-14-14-14"
229
+
230
+ hex2 = Electrologica.decode( str2 ) ## text to (binary) number
231
+ pp hex
232
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
233
+ pp hex2
234
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
235
+ pp hex == hex2
236
+ # => true
237
+ ```
238
+
239
+ or
240
+
241
+
242
+ ``` ruby
243
+ Base32.format = :electrologica
244
+
245
+ str = Base32.encode( hex ) ## (binary) number to text
246
+ pp str
247
+ # => "09-09-09-09-06-07-07-04-01-01-14-01-09-15-14-14-00-05-05-00-06-06-04-04-13-08-06-08-01-03-03-00-05-05-05-06-06-05-05-03-09-08-09-09-11-14-14-14"
248
+ pp Base32.fmt( str )
249
+ # => "09-09-09-09 06-07-07-04 01-01-14-01 09-15-14-14 00-05-05-00 06-06-04-04 13-08-06-08 01-03-03-00 05-05-05-06 06-05-05-03 09-08-09-09 11-14-14-14"
250
+ pp = Base32.decode( str ) ## text to (binary) number
251
+ # => 512955438081049600613224346938352058409509756310147795204209859701881294
252
+ ```
253
+
254
+
255
+
256
+
257
+ ## License
258
+
259
+ The `base32-alphabets` scripts are dedicated to the public domain.
260
+ Use it as you please with no restrictions whatsoever.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require 'hoe'
2
+ require './lib/base32-alphabets/version.rb'
3
+
4
+ Hoe.spec 'base32-alphabets' do
5
+
6
+ self.version = Base32::VERSION
7
+
8
+ self.summary = "base32-alphabets - base32 (2^5) encoding / decoding in 5-bit groups with kai, crockford or electrologica notation / alphabet"
9
+ self.description = summary
10
+
11
+ self.urls = ['https://github.com/cryptocopycats/base32-alphabets']
12
+
13
+ self.author = 'Gerald Bauer'
14
+ self.email = 'wwwmake@googlegroups.com'
15
+
16
+ # switch extension to .markdown for gihub formatting
17
+ self.readme_file = 'README.md'
18
+ self.history_file = 'HISTORY.md'
19
+
20
+ self.extra_deps = [
21
+ ]
22
+
23
+ self.licenses = ['Public Domain']
24
+
25
+ self.spec_extras = {
26
+ required_ruby_version: '>= 2.3'
27
+ }
28
+
29
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+
3
+ require 'pp'
4
+
5
+
6
+ ## our own code
7
+ require 'base32-alphabets/version' # note: let version always go first
8
+
9
+ require 'base32-alphabets/base'
10
+ require 'base32-alphabets/kai'
11
+ require 'base32-alphabets/crockford'
12
+ require 'base32-alphabets/electrologica'
13
+ require 'base32-alphabets/base32'
14
+
15
+
16
+
17
+
18
+
19
+ ## add a shortcut (convenience) alias
20
+ Kai = Base32::Kai
21
+ Crockford = Base32::Crockford
22
+ Electrologica = Base32::Electrologica
23
+
24
+
25
+ def encode32( num ) Base32.encode( num ); end
26
+ def decode32( num ) Base32.decode( str ); end
27
+
28
+
29
+
30
+ # say hello
31
+ puts Base32.banner if $DEBUG || (defined?($RUBYCOCO_DEBUG) && $RUBYCOCO_DEBUG)
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+
3
+ #########
4
+ ## shared code for formats / variants with single char alphabets
5
+ ## e.g. Kai, Crockford, ...
6
+
7
+ module Base32
8
+ class Base
9
+
10
+ # Converts a base10 integer to a base32 string.
11
+ def self.encode( num, klass: )
12
+ buf = String.new
13
+ while num >= BASE
14
+ ## puts "num=#{num}"
15
+ mod = num % BASE
16
+ ## puts " mod=#{mod} == #{klass::ALPHABET[mod]}"
17
+ buf = klass::ALPHABET[mod] + buf
18
+ ## puts "buf=#{buf}"
19
+ num = (num - mod)/BASE
20
+ end
21
+ klass::ALPHABET[num] + buf
22
+ end
23
+
24
+
25
+
26
+ # Converts a base32 string to a base10 integer.
27
+ def self.decode( str, klass: )
28
+ ## note: allow spaces or dashes (-); remove them all first
29
+ str = str.tr( ' -', '' )
30
+
31
+ num = 0
32
+ str.reverse.each_char.with_index do |char,index|
33
+ code = klass::NUMBER[char]
34
+ raise ArgumentError, "Value passed not a valid base32 string - >#{char}< not found in alphabet" if code.nil?
35
+ num += code * (BASE**(index))
36
+ end
37
+ num
38
+ end
39
+
40
+
41
+
42
+
43
+ def self.fmt( str )
44
+ ## note: allow spaces or dashes (-); remove them all first
45
+ str = str.tr( ' -', '' )
46
+
47
+ ## format in groups of four (4) separated by space
48
+ ## e.g. ccac7787fa7fafaa16467755f9ee444467667366cccceede
49
+ ## : ccac 7787 fa7f afaa 1646 7755 f9ee 4444 6766 7366 cccc eede
50
+ str.reverse.gsub( /(.{4})/, '\1 ').reverse.strip
51
+ end
52
+
53
+
54
+
55
+ ########################
56
+ ## (private) helpers
57
+ def self.build_binary( alphabet )
58
+ alphabet.each_with_index.reduce({}) do |h, (char,index)|
59
+ # puts "#{char} => #{index} #{'%05b' % index}"
60
+ h[char] = '%05b' % index
61
+ h
62
+ end
63
+ end
64
+
65
+ end # class Base
66
+ end # module Base32
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ module Base32 ## Base32 (2^5 - 5-bits)
5
+
6
+ BASE = 32 # ALPHABET.length == 32 ## 32 chars/letters/digits
7
+
8
+
9
+ class Configuration
10
+ attr_reader :format
11
+
12
+ MAPPING = {
13
+ kai: Kai, # starts counting at 1 (one)
14
+ crockford: Crockford, # starts counting at 0 (zero)
15
+ hex: Crockford, # note: use hex as an alias - why? why not?
16
+ electrologica: Electrologica,
17
+ num: Electrologica, # note: use num as an alias
18
+ }
19
+
20
+ def initialize
21
+ @format = Kai
22
+ end
23
+
24
+ def format=(value)
25
+ if value.is_a? Symbol
26
+ @format = MAPPING[ value ]
27
+ else ## assume class
28
+ @format = value
29
+ end
30
+ end
31
+ end # class Configuration
32
+
33
+ ## lets you use
34
+ ## Base32.configure do |config|
35
+ ## config.format = :kai
36
+ ## end
37
+
38
+ def self.configuration
39
+ @configuration ||= Configuration.new
40
+ end
41
+
42
+ def self.configure
43
+ yield( configuration )
44
+ end
45
+
46
+ ## add convenience helper for format
47
+ def self.format() configuration.format; end
48
+ def self.format=(value) self.configuration.format = value; end
49
+
50
+
51
+
52
+ def self.encode( num, klass: configuration.format ) klass.encode( num ); end
53
+ def self.decode( str, klass: configuration.format ) klass.decode( str ); end
54
+ def self.fmt( str, klass: configuration.format ) klass.fmt( str ); end
55
+
56
+ ## encoding alphabet - letter-to-number by index / array
57
+ def self.alphabet( klass: configuration.format ) klass::ALPHABET; end
58
+ ## decoding number-to-letter mapping / hash
59
+ def self.number( klass: configuration.format ) klass::NUMBER; end
60
+
61
+ end # module Base32
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ #####################
4
+ # Base32 Encoding - Crockford (by Douglas Crockford)
5
+ # see https://www.crockford.com/wrmg/base32.html
6
+
7
+
8
+ module Base32
9
+ class Crockford < Base
10
+
11
+ ALPHABET = %w[ 0 1 2 3 4 5 6 7
12
+ 8 9 a b c d e f
13
+ g h j k m n p q
14
+ r s t v w x y z]
15
+
16
+ def self.encode( num ) super( num, klass: self ); end
17
+
18
+
19
+ NUMBER = { ## rename INTEGER /INT - why? why not??
20
+ '0' => 0, 'o' => 0, 'O'=> 0,
21
+ '1' => 1, 'l' => 1, 'L'=> 1, 'i'=> 1, 'I' => 1,
22
+ '2' => 2,
23
+ '3' => 3,
24
+ '4' => 4,
25
+ '5' => 5,
26
+ '6' => 6,
27
+ '7' => 7,
28
+ '8' => 8,
29
+ '9' => 9,
30
+ 'a' => 10, 'A' => 10,
31
+ 'b' => 11, 'B' => 11,
32
+ 'c' => 12, 'C' => 12,
33
+ 'd' => 13, 'D' => 13,
34
+ 'e' => 14, 'E' => 14,
35
+ 'f' => 15, 'F' => 15,
36
+ 'g' => 16, 'G' => 16,
37
+ 'h' => 17, 'H' => 17,
38
+ 'j' => 18, 'J' => 18,
39
+ 'k' => 19, 'K' => 19,
40
+ 'm' => 20, 'M' => 20,
41
+ 'n' => 21, 'N' => 21,
42
+ 'p' => 22, 'P' => 22,
43
+ 'q' => 23, 'Q' => 23,
44
+ 'r' => 24, 'R' => 24,
45
+ 's' => 25, 'S' => 25,
46
+ 't' => 26, 'T' => 26,
47
+ 'v' => 27, 'V' => 27,
48
+ 'w' => 28, 'W' => 28,
49
+ 'x' => 29, 'X' => 29,
50
+ 'y' => 30, 'Y' => 30,
51
+ 'z' => 31, 'Z' => 31
52
+ }
53
+
54
+ def self.decode( str ) super( str, klass: self ); end
55
+
56
+
57
+ ## simple hash map (helper) for conversion to binary string
58
+ BINARY = build_binary( ALPHABET )
59
+
60
+ ## add shortcuts (convenience) aliases
61
+ BIN = BINARY
62
+ NUM = NUMBER
63
+
64
+ end # class Crockford
65
+ end # module Base32
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+
3
+ module Base32
4
+ class Electrologica ## Base32 (2^5 - 5-bits)
5
+
6
+ ALPHABET = %w[ 00 01 02 03 04 05 06 07
7
+ 08 09 10 11 12 13 14 15
8
+ 16 17 18 19 20 21 22 23
9
+ 24 25 26 27 28 29 30 31 ]
10
+
11
+ # Converts a base10 integer to a base32 string.
12
+ def self.encode( num )
13
+ buf = String.new
14
+ while num >= BASE
15
+ # puts "num=#{num}"
16
+ mod = num % BASE
17
+ # puts " mod=#{mod} == #{ALPHABET[mod]}"
18
+ buf = "-" + ALPHABET[mod] + buf ## note: add - separator
19
+ # puts "buf=#{buf}"
20
+ num = (num - mod)/BASE
21
+ end
22
+ ALPHABET[num] + buf
23
+ end
24
+
25
+ ## Note:
26
+ ## for decoding allow (misspelled) l/L for 1
27
+ ## and (misspelled) 0 for o/O - why? why not?
28
+ ## and UPPERCASE letters - why? why not?
29
+
30
+ NUMBER = { ## rename INTEGER /INT - why? why not??
31
+ '00' => 0, '0' => 0,
32
+ '01' => 1, '1' => 1,
33
+ '02' => 2, '2' => 2,
34
+ '03' => 3, '3' => 3,
35
+ '04' => 4, '4' => 4,
36
+ '05' => 5, '5' => 5,
37
+ '06' => 6, '6' => 6,
38
+ '07' => 7, '7' => 7,
39
+ '08' => 8, '8' => 8,
40
+ '09' => 9, '9' => 9,
41
+ '10' => 10,
42
+ '11' => 11,
43
+ '12' => 12,
44
+ '13' => 13,
45
+ '14' => 14,
46
+ '15' => 15,
47
+ '16' => 16,
48
+ '17' => 17,
49
+ '18' => 18,
50
+ '19' => 19,
51
+ '20' => 20,
52
+ '21' => 21,
53
+ '22' => 22,
54
+ '23' => 23,
55
+ '24' => 24,
56
+ '25' => 25,
57
+ '26' => 26,
58
+ '27' => 27,
59
+ '28' => 28,
60
+ '29' => 29,
61
+ '30' => 30,
62
+ '31' => 31,
63
+ }
64
+
65
+
66
+ ## add shortcuts (convenience) aliases
67
+ ## BIN = BINARY
68
+ NUM = NUMBER
69
+
70
+ # Converts a base32 string to a base10 integer.
71
+ def self.decode( str )
72
+ ## note: allow spaces or slash (/) for dashes (-)
73
+ str = str.strip ## remove leading and trailing spaces (first)
74
+ str = str.tr( ' /', '-' )
75
+ str = str.gsub( /-{2,}/, '-' ) ## fold more than one dash into one
76
+
77
+ num = 0
78
+ str.split('-').reverse.each.with_index do |char,index|
79
+ code = NUMBER[char]
80
+ raise ArgumentError, "Value passed not a valid base32 string - >#{char}< not found in alphabet" if code.nil?
81
+ num += code * (BASE**(index))
82
+ end
83
+ num
84
+ end
85
+
86
+
87
+ def self.fmt( str, sep: '-' )
88
+ ## note: allow spaces or slash (/) for dashes (-)
89
+ str = str.strip ## remove leading and trailing spaces (first)
90
+ str = str.tr( ' /', '-' )
91
+ str = str.gsub( /-{2,}/, '-' ) ## fold more than one dash into one
92
+
93
+ ## format in groups of four (4) separated by space
94
+ ## e.g. ccac7787fa7fafaa16467755f9ee444467667366cccceede
95
+ ## : ccac 7787 fa7f afaa 1646 7755 f9ee 4444 6766 7366 cccc eede
96
+
97
+ ## note: use reverse - if not divided by four that leading slice gets cut short
98
+ str.split('-').reverse.each_slice(4).map { |slice| slice.reverse.join( sep ) }.reverse.join( ' ' )
99
+ end
100
+
101
+ end # class Electrologica
102
+ end # module Base32
@@ -0,0 +1,108 @@
1
+ # encoding: utf-8
2
+
3
+ #####################
4
+ # why kai?
5
+ # in honor of Kaigani who deciphered the genes - thanks!
6
+ # see https://medium.com/@kaigani/the-cryptokitties-genome-project-on-dominance-inheritance-and-mutation-b73059dcd0a4
7
+
8
+
9
+ module Base32
10
+ class Kai < Base
11
+ # See https://en.wikipedia.org/wiki/Base58
12
+ ## Note: aplpabet used for encoding
13
+ ALPHABET = %w[ 1 2 3 4 5 6 7 8
14
+ 9 a b c d e f g
15
+ h i j k m n o p
16
+ q r s t u v w x]
17
+
18
+ def self.encode( num ) super( num, klass: self ); end
19
+
20
+ ## Note:
21
+ ## for decoding allow (misspelled) l/L for 1
22
+ ## and (misspelled) 0 for o/O - why? why not?
23
+ ## and UPPERCASE letters - why? why not?
24
+
25
+ NUMBER = { ## rename INTEGER /INT - why? why not??
26
+ '1' => 0, 'l' => 0, 'L'=> 0,
27
+ '2' => 1,
28
+ '3' => 2,
29
+ '4' => 3,
30
+ '5' => 4,
31
+ '6' => 5,
32
+ '7' => 6,
33
+ '8' => 7,
34
+ '9' => 8,
35
+ 'a' => 9, 'A' => 9,
36
+ 'b' => 10, 'B' => 10,
37
+ 'c' => 11, 'C' => 11,
38
+ 'd' => 12, 'D' => 12,
39
+ 'e' => 13, 'E' => 13,
40
+ 'f' => 14, 'F' => 14,
41
+ 'g' => 15, 'G' => 15,
42
+ 'h' => 16, 'H' => 16,
43
+ 'i' => 17, 'I' => 17,
44
+ 'j' => 18, 'J' => 18,
45
+ 'k' => 19, 'K' => 19,
46
+ 'm' => 20, 'M' => 20,
47
+ 'n' => 21, 'N' => 21,
48
+ 'o' => 22, 'O' => 22, '0' => 22,
49
+ 'p' => 23, 'P' => 23,
50
+ 'q' => 24, 'Q' => 24,
51
+ 'r' => 25, 'R' => 25,
52
+ 's' => 26, 'S' => 26,
53
+ 't' => 27, 'T' => 27,
54
+ 'u' => 28, 'U' => 28,
55
+ 'v' => 29, 'V' => 29,
56
+ 'w' => 30, 'W' => 30,
57
+ 'x' => 31, 'X' => 31
58
+ }
59
+
60
+ def self.decode( str ) super( str, klass: self ); end
61
+
62
+
63
+ =begin
64
+ BINARY = {
65
+ '1' => '00000', # 0
66
+ '2' => '00001', # 1
67
+ '3' => '00010', # 2
68
+ '4' => '00011', # 3
69
+ '5' => '00100', # 4
70
+ '6' => '00101', # 5
71
+ '7' => '00110', # 6
72
+ '8' => '00111', # 7
73
+ '9' => '01000', # 8
74
+ 'a' => '01001', # 9
75
+ 'b' => '01010', # 10
76
+ 'c' => '01011', # 11
77
+ 'd' => '01100', # 12
78
+ 'e' => '01101', # 13
79
+ 'f' => '01110', # 14
80
+ 'g' => '01111', # 15
81
+ 'h' => '10000', # 16
82
+ 'i' => '10001', # 17
83
+ 'j' => '10010', # 18
84
+ 'k' => '10011', # 19
85
+ 'm' => '10100', # 20
86
+ 'n' => '10101', # 21
87
+ 'o' => '10110', # 22
88
+ 'p' => '10111', # 23
89
+ 'q' => '11000', # 24
90
+ 'r' => '11001', # 25
91
+ 's' => '11010', # 26
92
+ 't' => '11011', # 27
93
+ 'u' => '11100', # 28
94
+ 'v' => '11101', # 29
95
+ 'w' => '11110', # 30
96
+ 'x' => '11111' # 31
97
+ }
98
+ =end
99
+
100
+ ## simple hash map (helper) for conversion to binary string
101
+ BINARY = build_binary( ALPHABET )
102
+
103
+ ## add shortcuts (convenience) aliases
104
+ BIN = BINARY
105
+ NUM = NUMBER
106
+
107
+ end # class Kai
108
+ end # module Base32
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module Base32
4
+
5
+
6
+ MAJOR = 1
7
+ MINOR = 0
8
+ PATCH = 0
9
+ VERSION = [MAJOR,MINOR,PATCH].join('.')
10
+
11
+ def self.version
12
+ VERSION
13
+ end
14
+
15
+ def self.banner
16
+ "base32-alphabets/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
17
+ end
18
+
19
+ def self.root
20
+ "#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
21
+ end
22
+
23
+ end # module Base32
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ ## $:.unshift(File.dirname(__FILE__))
2
+
3
+ ## minitest setup
4
+
5
+ require 'minitest/autorun'
6
+
7
+
8
+ ## our own code
9
+
10
+ require 'base32-alphabets'
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_base32.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+
11
+ class TestBase32 < MiniTest::Test
12
+
13
+
14
+ def test_kai
15
+
16
+ ## Kitty #1001
17
+ ## see https://cryptokittydex.com/kitties/1001
18
+
19
+ binary = 0b0000000000000000010010100101001010010011000111001110010000001000010111000001010010111101110011100000000101001010000000110001100010000100011010100000110010000000100011000110000000101001010010100110001100010100101000110100101000010010100101011011100111001110 # binary
20
+ hex = 0x00004a52931ce4085c14bdce014a0318846a0c808c60294a6314a34a_1295_b9ce # hex
21
+
22
+ kai_fmt = "aaaa 7885 22f2 agff 1661 7755 e979 2441 6667 7664 a9aa cfff"
23
+ kai = kai_fmt.gsub( ' ', '' )
24
+
25
+ assert_equal binary, hex
26
+
27
+ puts "binary number:"
28
+ pp binary
29
+ puts "hex number:"
30
+ pp hex
31
+
32
+ Base32.format = :kai
33
+ kai2 = Base32.encode( hex )
34
+ pp kai
35
+ pp kai2
36
+
37
+ assert_equal kai, kai2
38
+ assert_equal kai_fmt, Base32::Kai.fmt( kai2 )
39
+
40
+
41
+ hex2 = Base32.decode( kai2 )
42
+ pp hex2
43
+ assert_equal hex, hex2
44
+
45
+ kai3 = Base32::Kai.encode( hex )
46
+ hex3 = Base32::Kai.decode( kai3 )
47
+ assert_equal hex, hex3
48
+ assert_equal kai, kai3
49
+
50
+ puts "kai.length: #{kai.length}" ## 48
51
+ puts " first: #{kai[0]}"
52
+ puts " last: #{kai[-1]}"
53
+ puts " last: #{kai[47]}"
54
+
55
+ puts kai.reverse
56
+ puts kai.reverse[0,4]
57
+ puts kai.reverse[4,4]
58
+ puts kai.reverse[8,4]
59
+ eyes = kai.reverse[12,4]
60
+ puts "eyes:"
61
+ puts eyes
62
+
63
+ color1 = kai.reverse[16,4]
64
+ puts "color1:"
65
+ puts color1
66
+ pp color1[0]
67
+ end
68
+
69
+
70
+ end # class TestBase32
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_base32_crockford.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+
11
+ class TestBase32Crockford < MiniTest::Test
12
+
13
+ def test_encoding_and_decoding_single_chars
14
+ from = (0..31).to_a
15
+ to = %w[ 0 1 2 3 4 5 6 7 8 9 a b c d e f g h j k m n p q r s t v w x y z]
16
+
17
+ from.zip(to) do |symbol_value, encode_symbol|
18
+ assert_equal encode_symbol, Base32::Crockford.encode( symbol_value )
19
+ assert_equal symbol_value, Base32::Crockford.decode( encode_symbol )
20
+ end
21
+ end
22
+
23
+ def test_encoding_larger_numbers
24
+ assert_equal '10', Base32::Crockford.encode( 32 )
25
+ assert_equal '16j', Base32::Crockford.encode( 1234 )
26
+ end
27
+
28
+ def test_decoding_strings
29
+ assert_equal 1234, Base32::Crockford.decode( '16j' )
30
+ end
31
+
32
+ def test_decoding_normalizes_symbols
33
+ assert_equal Base32::Crockford.decode('11100110'),
34
+ Base32::Crockford.decode('IL1O0ilo')
35
+ end
36
+
37
+ def test_decoding_lowercase
38
+ assert_equal Base32::Crockford.decode('abcdefghijklmnopqrstvwxyz'),
39
+ Base32::Crockford.decode('ABCDEFGHIJKLMNOPQRSTVWXYZ')
40
+ end
41
+
42
+ def test_decode_should_ignore_hyphens
43
+ assert_equal 1234, Base32::Crockford.decode('1-6-j')
44
+ end
45
+
46
+ def test_decoding_invalid_strings
47
+ assert_raises(ArgumentError) { Base32::Crockford.decode("'+?") }
48
+ end
49
+
50
+
51
+ =begin
52
+ def test_length_and_hyphenization
53
+ assert_equal "0016J", Base32::Crockford.encode(1234, :length => 5)
54
+ assert_equal "0-01-6J",
55
+ Base32::Crockford.encode(1234, :length => 5, :split => 2)
56
+ assert_equal "00-010",
57
+ Base32::Crockford.encode(32, :length => 5, :split => 3)
58
+ end
59
+ =end
60
+
61
+ end # class TestBase32Crockford
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: base32-alphabets
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Gerald Bauer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-12-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdoc
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: hoe
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.16'
41
+ description: base32-alphabets - base32 (2^5) encoding / decoding in 5-bit groups with
42
+ kai, crockford or electrologica notation / alphabet
43
+ email: wwwmake@googlegroups.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files:
47
+ - HISTORY.md
48
+ - LICENSE.md
49
+ - Manifest.txt
50
+ - README.md
51
+ files:
52
+ - HISTORY.md
53
+ - LICENSE.md
54
+ - Manifest.txt
55
+ - README.md
56
+ - Rakefile
57
+ - lib/base32-alphabets.rb
58
+ - lib/base32-alphabets/base.rb
59
+ - lib/base32-alphabets/base32.rb
60
+ - lib/base32-alphabets/crockford.rb
61
+ - lib/base32-alphabets/electrologica.rb
62
+ - lib/base32-alphabets/kai.rb
63
+ - lib/base32-alphabets/version.rb
64
+ - test/helper.rb
65
+ - test/test_base32.rb
66
+ - test/test_base32_crockford.rb
67
+ homepage: https://github.com/cryptocopycats/base32-alphabets
68
+ licenses:
69
+ - Public Domain
70
+ metadata: {}
71
+ post_install_message:
72
+ rdoc_options:
73
+ - "--main"
74
+ - README.md
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '2.3'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.5.2
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: base32-alphabets - base32 (2^5) encoding / decoding in 5-bit groups with
93
+ kai, crockford or electrologica notation / alphabet
94
+ test_files: []