base32-url 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +21 -0
- data/README.md +26 -3
- data/lib/base32/url.rb +28 -31
- data/lib/base32/version.rb +1 -1
- data/test/test_base32_url.rb +12 -12
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2636154ecf4c12b4aebc6f7d902512a068caa8d119a66222e4c6bc5f986b550a
|
4
|
+
data.tar.gz: 1a6f5b368de218189acde3401611f116182e48318739c3b417cd3356cbc9ff09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 017d4b5c6246fbd756c03a39cc6746ccafe5fde79d2620f62321dd2ebc24c9ce4121ca1aecb1f03c26834c636806e0eeec7081f1a9260df8e9bae51d6b8cebac
|
7
|
+
data.tar.gz: fa73fb138288c1cec305373c74fa5e690129b52a066bf27e754f357912acf37b19767b588bac710dabfd151d6199d8869a2e8ffcf5d72da56c5a82e0c44bb032
|
data/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 DataCite
|
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
CHANGED
@@ -5,7 +5,7 @@ An implementation of Douglas Crockfords Base32-Encoding in Ruby, with two modifi
|
|
5
5
|
the resulting strings more URL friendly:
|
6
6
|
|
7
7
|
* use lower case characters
|
8
|
-
*
|
8
|
+
* use two digits (mod 97-10, ISO 7064) for the checksum
|
9
9
|
|
10
10
|
see <http://www.crockford.com/wrmg/base32.html>
|
11
11
|
|
@@ -18,6 +18,7 @@ $ gem install base32-url
|
|
18
18
|
## Changes
|
19
19
|
|
20
20
|
```
|
21
|
+
0.5.0 - use mod 97-10 (ISO 7064) to calculate checksum
|
21
22
|
0.3.0 - encode into lower case characters, use * ~ _ ^ u for checksum
|
22
23
|
0.2.0 - added optional checksum
|
23
24
|
```
|
@@ -32,5 +33,27 @@ require 'base32/url'
|
|
32
33
|
Base32::URL.encode(1234) # => "16j"
|
33
34
|
Base32::URL.encode(100**10, :split=>5, :length=>15) # => "02pqh-ty5nh-h0000"
|
34
35
|
Base32::URL.decode("2pqh-ty5nh-hoooo") # => 10**100
|
35
|
-
Base32::URL.encode(1234, checksum: true) # => "
|
36
|
-
Base32::URL.decode("
|
36
|
+
Base32::URL.encode(1234, checksum: true) # => "16j82"
|
37
|
+
Base32::URL.decode("16j82", checksum: true) # => 1234
|
38
|
+
```
|
39
|
+
|
40
|
+
## Development
|
41
|
+
|
42
|
+
We use test-unit for unit testing:
|
43
|
+
|
44
|
+
```
|
45
|
+
bundle exec rake
|
46
|
+
```
|
47
|
+
|
48
|
+
Follow along via [Github Issues](https://github.com/datacite/base32-url/issues).
|
49
|
+
|
50
|
+
### Note on Patches/Pull Requests
|
51
|
+
|
52
|
+
* Fork the project
|
53
|
+
* Write tests for your new feature or a test that reproduces a bug
|
54
|
+
* Implement your feature or make a bug fix
|
55
|
+
* Do not mess with Rakefile, version or history
|
56
|
+
* Commit, push and make a pull request. Bonus points for topical branches.
|
57
|
+
|
58
|
+
## License
|
59
|
+
**base32-url** is released under the [MIT License](https://github.com/datacite/base32-url/blob/master/LICENSE.md).
|
data/lib/base32/url.rb
CHANGED
@@ -9,26 +9,22 @@ require 'enumerator'
|
|
9
9
|
module Base32
|
10
10
|
end
|
11
11
|
|
12
|
-
# encode a value with the encoding defined by _Douglas_ _Crockford_ in
|
13
|
-
# <http://www.crockford.com/wrmg/base32.html>
|
14
|
-
#
|
15
12
|
# this is *not* the same as the Base32 encoding defined in RFC 4648
|
16
13
|
#
|
17
|
-
#
|
18
14
|
# The Base32 symbol set is a superset of the Base16 symbol set.
|
19
15
|
#
|
20
16
|
# We chose a symbol set of 10 digits and 22 letters. We exclude 4 of the 26
|
21
|
-
# letters:
|
17
|
+
# letters: i l o u.
|
22
18
|
#
|
23
19
|
# Excluded Letters
|
24
20
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
21
|
+
# i:: Can be confused with 1
|
22
|
+
# l:: Can be confused with 1
|
23
|
+
# o:: Can be confused with 0
|
24
|
+
# u:: Accidental obscenity
|
29
25
|
#
|
30
26
|
# When decoding, upper and lower case letters are accepted, and i and l will
|
31
|
-
# be treated as 1 and o will be treated as 0. When encoding, lower
|
27
|
+
# be treated as 1 and o will be treated as 0. When encoding, lower case
|
32
28
|
# letters are used.
|
33
29
|
#
|
34
30
|
# If the bit-length of the number to be encoded is not a multiple of 5 bits,
|
@@ -44,19 +40,15 @@ class Base32::URL
|
|
44
40
|
ENCODE_CHARS =
|
45
41
|
%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 ?)
|
46
42
|
|
47
|
-
DECODE_MAP = ENCODE_CHARS.to_enum(:each_with_index).
|
48
|
-
|
43
|
+
DECODE_MAP = ENCODE_CHARS.to_enum(:each_with_index).reduce({}) do |hsh, (c,i)|
|
44
|
+
hsh[c] = i
|
45
|
+
hsh
|
49
46
|
end.merge({'i' => 1, 'l' => 1, 'o' => 0})
|
50
47
|
|
51
|
-
CHECKSUM_CHARS = %w(i l o u)
|
52
|
-
|
53
|
-
CHECKSUM_MAP = { "i" => 32, "l" => 33, "o" => 34, "u" => 35 }
|
54
|
-
|
55
48
|
# encodes an integer into a string
|
56
49
|
#
|
57
50
|
# when +checksum+ is given, a checksum is added at the end of the the string,
|
58
|
-
# calculated as modulo
|
59
|
-
# used for symbol values 32-35
|
51
|
+
# calculated as modulo 97-10 (ISO 7064)
|
60
52
|
#
|
61
53
|
# when +split+ is given a hyphen is inserted every <n> characters to improve
|
62
54
|
# readability
|
@@ -75,7 +67,10 @@ class Base32::URL
|
|
75
67
|
ENCODE_CHARS[bits.reverse.to_i(2)]
|
76
68
|
end.reverse.join
|
77
69
|
|
78
|
-
|
70
|
+
if opts[:checksum]
|
71
|
+
remainder = 98 - ((number * 100) % 97)
|
72
|
+
str += sprintf("%02d", remainder)
|
73
|
+
end
|
79
74
|
|
80
75
|
str = str.rjust(opts[:length], '0') if opts[:length]
|
81
76
|
|
@@ -96,30 +91,29 @@ class Base32::URL
|
|
96
91
|
# I,i,l,L decodes to 1
|
97
92
|
# O,o decodes to 0
|
98
93
|
#
|
99
|
-
# Base32::
|
100
|
-
# Base32::
|
101
|
-
# Base32::
|
94
|
+
# Base32::URL.decode("16J") # => 1234
|
95
|
+
# Base32::URL.decode("OI") # => 1
|
96
|
+
# Base32::URL.decode("3G923-0VQVS") # => 123456789012345
|
102
97
|
#
|
103
98
|
# returns +nil+ if the string contains invalid characters and can't be
|
104
99
|
# decoded, or if checksum option is used and checksum is incorrect
|
105
|
-
|
100
|
+
|
106
101
|
def self.decode(string, opts = {})
|
107
|
-
if opts[:checksum]
|
108
|
-
checksum_char = string.slice!(-1)
|
109
|
-
checksum_number = DECODE_MAP.merge(CHECKSUM_MAP)[checksum_char]
|
110
|
-
end
|
102
|
+
string, checksum = string[0..-3], string[-2..-1].to_i if opts[:checksum]
|
111
103
|
|
112
104
|
number = clean(string).split(//).map { |char|
|
113
105
|
DECODE_MAP[char] or return nil
|
114
106
|
}.inject(0) { |result,val| (result << 5) + val }
|
115
107
|
|
116
|
-
|
108
|
+
if opts[:checksum]
|
109
|
+
remainder = 98 - ((number * 100) % 97)
|
110
|
+
return nil if remainder != checksum
|
111
|
+
end
|
117
112
|
|
118
113
|
number
|
119
114
|
end
|
120
115
|
|
121
116
|
# same as decode, but raises ArgumentError when the string can't be decoded
|
122
|
-
#
|
123
117
|
def self.decode!(string, opts = {})
|
124
118
|
decode(string) or raise ArgumentError
|
125
119
|
end
|
@@ -130,13 +124,16 @@ class Base32::URL
|
|
130
124
|
# replaces invalid characters with a question mark ('?')
|
131
125
|
#
|
132
126
|
def self.normalize(string, opts = {})
|
133
|
-
|
127
|
+
if opts[:checksum]
|
128
|
+
checksum = string.split(//).last(2).join
|
129
|
+
string = string[0..-2]
|
130
|
+
end
|
134
131
|
|
135
132
|
string = clean(string).split(//).map do |char|
|
136
133
|
ENCODE_CHARS[DECODE_MAP[char] || 32]
|
137
134
|
end.join
|
138
135
|
|
139
|
-
string +=
|
136
|
+
string += checksum if opts[:checksum]
|
140
137
|
|
141
138
|
string
|
142
139
|
end
|
data/lib/base32/version.rb
CHANGED
data/test/test_base32_url.rb
CHANGED
@@ -21,7 +21,7 @@ class TestBase32Url < Test::Unit::TestCase
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_decoding_strings
|
24
|
-
assert_equal(1234, Base32::URL.decode("
|
24
|
+
assert_equal(1234, Base32::URL.decode("16j"))
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_decoding_normalizes_symbols
|
@@ -50,8 +50,8 @@ class TestBase32Url < Test::Unit::TestCase
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_normalize_with_checksum
|
53
|
-
assert_equal "b?
|
54
|
-
assert_equal "
|
53
|
+
assert_equal "b?1223", Base32::URL.normalize("BU-123", :checksum => true)
|
54
|
+
assert_equal "b1223", Base32::URL.normalize("B123", :checksum => true)
|
55
55
|
end
|
56
56
|
|
57
57
|
def test_valid
|
@@ -73,25 +73,25 @@ class TestBase32Url < Test::Unit::TestCase
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def test_encoding_checksum
|
76
|
-
assert_equal "
|
76
|
+
assert_equal "16j82",
|
77
77
|
Base32::URL.encode(1234, :checksum => true)
|
78
|
-
assert_equal "
|
79
|
-
Base32::URL.encode(1234, :length =>
|
80
|
-
assert_equal "
|
81
|
-
Base32::URL.encode(1234, :length =>
|
78
|
+
assert_equal "016j82",
|
79
|
+
Base32::URL.encode(1234, :length => 6, :checksum => true)
|
80
|
+
assert_equal "01-6j-82",
|
81
|
+
Base32::URL.encode(1234, :length => 6, :split => 2, :checksum => true)
|
82
82
|
end
|
83
83
|
|
84
84
|
def test_decoding_checksum
|
85
85
|
assert_equal 1234,
|
86
|
-
Base32::URL.decode("
|
86
|
+
Base32::URL.decode("16j82", :checksum => true)
|
87
87
|
assert_equal 1234,
|
88
|
-
Base32::URL.decode("
|
88
|
+
Base32::URL.decode("016j82", :length => 6, :checksum => true)
|
89
89
|
assert_equal 1234,
|
90
|
-
Base32::URL.decode("
|
90
|
+
Base32::URL.decode("01-6j-82", :length => 6, :split => 2, :checksum => true)
|
91
91
|
end
|
92
92
|
|
93
93
|
def test_decoding_invalid_checksum
|
94
94
|
assert_equal nil,
|
95
|
-
Base32::URL.decode("
|
95
|
+
Base32::URL.decode("16j44", :checksum => true)
|
96
96
|
end
|
97
97
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: base32-url
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Fenner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01
|
11
|
+
date: 2018-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- ".gitignore"
|
65
65
|
- ".travis.yml"
|
66
66
|
- Gemfile
|
67
|
+
- LICENSE.md
|
67
68
|
- README.md
|
68
69
|
- Rakefile
|
69
70
|
- base32-url.gemspec
|