base32h 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/COPYING +14 -0
- data/README.md +42 -0
- data/lib/base32h.rb +173 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: de7e1abc9f5fbb560cd132ff8c7d11c0c8c91e3b751d2031988de46cc3072b7b
|
4
|
+
data.tar.gz: 734e6651e89a697c7d8faeee81351a235a2d3473215e027cd7b7cae1897685d6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2022dfbdefa1e442441a68118e1cc82a497f75f703e23f98b0078a6c93f482225ce21fc66388e826f76d6aa47b7401ae69075b43ce59d40837664a0aab1ecd68
|
7
|
+
data.tar.gz: 93b45da982c68477c84ff31ec3926038c24f26d1b1fb7aa94551b50bcf17a79f9e48099e4f1a10f334b20df25ca78dcecf89b725fe28549d8447cf7d8b9edc95
|
data/COPYING
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
Copyright (c) 2020 Ryan S. Northrup ("RyNo") <northrup@yellowapple.us>
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and distribute this software for any
|
4
|
+
purpose with or without fee is hereby granted, provided that the above
|
5
|
+
copyright notice and this permission notice appear in all copies.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
8
|
+
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
9
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
10
|
+
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
11
|
+
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
12
|
+
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
13
|
+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
14
|
+
PERFORMANCE OF THIS SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# `base32h.rb`
|
2
|
+
|
3
|
+
## What is it?
|
4
|
+
|
5
|
+
It's the third reference implementation of an encoder and decoder for
|
6
|
+
Base32H, a new(-ish) duotrigesimal (that is: base-32) number
|
7
|
+
representation, written as a gem for Ruby.
|
8
|
+
|
9
|
+
## How do I install it?
|
10
|
+
|
11
|
+
Run `gem install base32h`, or include it in your `Gemfile`, or
|
12
|
+
whatever you would normally do to install a gem.
|
13
|
+
|
14
|
+
## How do I hack it?
|
15
|
+
|
16
|
+
```bash
|
17
|
+
git clone --recursive https://github.com/base32h/base32h.rb.git
|
18
|
+
cd base32h.rb
|
19
|
+
rspec # to run the test suite
|
20
|
+
```
|
21
|
+
|
22
|
+
## How do I use it?
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'base32h'
|
26
|
+
|
27
|
+
Base32H.encode 17854910
|
28
|
+
# => "H0WDY"
|
29
|
+
|
30
|
+
Base32H.encode_bin "\xE3\xA9H\x83\x8D\xF5\xD5\x96\xD9\xD9"
|
31
|
+
# => "WELLH0WDYPARDNER"
|
32
|
+
|
33
|
+
Base32H.decode '88pzd'
|
34
|
+
# => 8675309
|
35
|
+
|
36
|
+
Base32H.decode_bin('2060w2g6009').unpack('C*')
|
37
|
+
# => [0, 0, 0, 8, 6, 7, 5, 3, 0, 9]
|
38
|
+
```
|
39
|
+
|
40
|
+
## Am I allowed to use it?
|
41
|
+
|
42
|
+
Yep! Just follow the terms of the ISC license (see `COPYING` in this repo).
|
data/lib/base32h.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
##
|
2
|
+
# This module provides Base32H encoding and decoding functions.
|
3
|
+
module Base32H
|
4
|
+
VERSION = "0.1.0"
|
5
|
+
|
6
|
+
extend self
|
7
|
+
|
8
|
+
##
|
9
|
+
# The complete list of Base32H digits, as an array of strings; the
|
10
|
+
# index of the array is the numeric value of the digit(s) in the
|
11
|
+
# string at that index. The first character in each string is the
|
12
|
+
# "canonical" digit (i.e. the one that Base32H-conformant encoders
|
13
|
+
# *must* emit for that value); all other characters (if present) are
|
14
|
+
# "aliases" (i.e. alternate forms of that digit that
|
15
|
+
# Base32H-conformant decoders *must* accept and correctly decode to
|
16
|
+
# that value).
|
17
|
+
#
|
18
|
+
# For example, +digits[27]+ returns +'VvUu'+, meaning that the
|
19
|
+
# "canonical" digit of value 27 is +V+, and that +v+, +U+, and +u+
|
20
|
+
# are all "aliases" of that canonical digit and decode to a value of
|
21
|
+
# 27.
|
22
|
+
def digits
|
23
|
+
['0Oo',
|
24
|
+
'1Ii',
|
25
|
+
'2',
|
26
|
+
'3',
|
27
|
+
'4',
|
28
|
+
'5Ss',
|
29
|
+
'6',
|
30
|
+
'7',
|
31
|
+
'8',
|
32
|
+
'9',
|
33
|
+
'Aa',
|
34
|
+
'Bb',
|
35
|
+
'Cc',
|
36
|
+
'Dd',
|
37
|
+
'Ee',
|
38
|
+
'Ff',
|
39
|
+
'Gg',
|
40
|
+
'Hh',
|
41
|
+
'Jj',
|
42
|
+
'Kk',
|
43
|
+
'Ll',
|
44
|
+
'Mm',
|
45
|
+
'Nn',
|
46
|
+
'Pp',
|
47
|
+
'Qq',
|
48
|
+
'Rr',
|
49
|
+
'Tt',
|
50
|
+
'VvUu',
|
51
|
+
'Ww',
|
52
|
+
'Xx',
|
53
|
+
'Yy',
|
54
|
+
'Zz']
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# :category: Encoding Digit
|
59
|
+
#
|
60
|
+
# Encodes an integer between 0 and 31 (inclusive) to its Base32H
|
61
|
+
# representation.
|
62
|
+
def encode_digit(d)
|
63
|
+
d = d.to_i
|
64
|
+
return nil unless (0..31).include? d
|
65
|
+
digits[d][0]
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# :category: Encoding Numeric
|
70
|
+
#
|
71
|
+
# Encodes an integer to its Base32H representation.
|
72
|
+
def encode(int)
|
73
|
+
rem = int.to_i.abs
|
74
|
+
out = []
|
75
|
+
return '0' if rem == 0
|
76
|
+
while rem > 0 do
|
77
|
+
out.unshift(encode_digit(rem % 32))
|
78
|
+
rem /= 32
|
79
|
+
end
|
80
|
+
out.join ''
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# :category: Encoding Binary
|
85
|
+
#
|
86
|
+
# Encodes a (binary) string to its Base32H representation.
|
87
|
+
def encode_bin(bin)
|
88
|
+
data = bin.unpack('C*')
|
89
|
+
extra = data.length % 5
|
90
|
+
data = ([0] * (5 - extra)) + data if extra > 0
|
91
|
+
out = []
|
92
|
+
data.each_slice(5) do |s|
|
93
|
+
chunk = bytes_to_u40 s
|
94
|
+
out.push encode(chunk).rjust(8, '0')
|
95
|
+
end
|
96
|
+
out.join ''
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# :category: Decoding Digit
|
101
|
+
#
|
102
|
+
# Decodes a single Base32H digit to its integer representation.
|
103
|
+
def decode_digit(d)
|
104
|
+
d = d.to_s
|
105
|
+
digits.find_index {|i| i.include? d}
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# :category: Decoding Numeric
|
110
|
+
#
|
111
|
+
# Decodes a Base32H number to its integer representation.
|
112
|
+
def decode(str)
|
113
|
+
res = str.to_s.chars.reverse.reduce({acc: 0, exp: 0}) do |state, char|
|
114
|
+
digit = decode_digit(char)
|
115
|
+
if digit.nil?
|
116
|
+
state
|
117
|
+
else
|
118
|
+
{acc: state[:acc] + (digit * 32**state[:exp]),
|
119
|
+
exp: state[:exp] + 1}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
res[:acc]
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# :category: Decoding Binary
|
127
|
+
#
|
128
|
+
# Decodes a Base32H binary into a string of packed unsigned bytes.
|
129
|
+
def decode_bin(str)
|
130
|
+
data = str.chars.reject {|c| decode_digit(c).nil?}
|
131
|
+
extra = data.length % 8
|
132
|
+
data = (['0'] * (8 - extra)) + data if extra > 0
|
133
|
+
out = []
|
134
|
+
data.each_slice(8) do |s|
|
135
|
+
chunk = u40_to_bytes decode(s.join '')
|
136
|
+
out += chunk
|
137
|
+
end
|
138
|
+
out.pack('C*')
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def u40_to_bytes(int)
|
144
|
+
rem = int.to_i.abs
|
145
|
+
out = []
|
146
|
+
while rem > 0 do
|
147
|
+
out.unshift(rem % 256)
|
148
|
+
rem /= 256
|
149
|
+
end
|
150
|
+
pad = 5 - out.length
|
151
|
+
out = ([0] * pad) + out if pad > 0
|
152
|
+
out
|
153
|
+
end
|
154
|
+
|
155
|
+
def bytes_to_u40(bytes)
|
156
|
+
bytes.reverse.reduce({acc:0,exp:0}) do |s,b|
|
157
|
+
{acc: s[:acc] + (b * 2**(8*s[:exp])),
|
158
|
+
exp: s[:exp] + 1}
|
159
|
+
end[:acc]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class Integer
|
164
|
+
def to_base32h
|
165
|
+
Base32H.encode(self)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class String
|
170
|
+
def to_base32h
|
171
|
+
Base32H.encode_bin(self)
|
172
|
+
end
|
173
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: base32h
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan S. Northrup ("RyNo")
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-10-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: An encoder/decoder library for Base32H
|
28
|
+
email: northrup@yellowapple.us
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- COPYING
|
34
|
+
- README.md
|
35
|
+
- lib/base32h.rb
|
36
|
+
homepage: https://base32h.github.io
|
37
|
+
licenses:
|
38
|
+
- ISC
|
39
|
+
metadata:
|
40
|
+
homepage_uri: https://base32h.github.io
|
41
|
+
source_code_uri: https://github.com/base32h/base32h.rb
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubygems_version: 3.1.2
|
58
|
+
signing_key:
|
59
|
+
specification_version: 4
|
60
|
+
summary: Base32H
|
61
|
+
test_files: []
|