base32-crockford-checksum 0.2.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 61c5a725b72dca942c6d42fb4604ad39a9f0e68c
4
+ data.tar.gz: 8c8c017e3de34c23c637d9d80345cc24d699497f
5
+ SHA512:
6
+ metadata.gz: 3cad2f783852a551f5e89a7e7052b0a38f1480c570380981ea5243288d59a566a299713b2c18f8dafb39858661b81790cb16365894c05e0955b47392f667a6e4
7
+ data.tar.gz: bc28de71354b16a088d013aabcfc7378e839d7208f1872c5c0a42e2be2db204e74b84580c6d37a390ec95e74ea5640fc643829448032529d64d3e8f1fb3cb6e9
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ doc
3
+ pkg
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.1
4
+ install:
5
+ - travis_retry bundle install
6
+ script: bundle exec rake
7
+ deploy:
8
+ provider: rubygems
9
+ api_key:
10
+ secure: tFWk9ydCPbprtN9s/tooTArCkkOGtD2b5vV8O3yOqpMBpdV1O1wERNbAj4NCjQJ8Hshe4DBp857JlEs3+8rnh0WMbOQgBNWQpGd6u22+YKSuIYchEmxnWAoYif6k6/TfYO1vmwI6/9sFqBfRu1k2/kZxAHG1M0VyolIYWGUDwXUY+u3pwStOAUH01nb3bHmjhc5SJ2kETAGAOIW4LPSJ/826IoOVIwqq+9VJnMR/tZmMf5uXIbEE9OWu883+L7y6nkBtn0528EZav7BATa4QB+mmaa0atIrsgGymEpheADhmWcUKTSydwOO+txuR/zar3E1p5ELyfI465QuPAt6f4/zfAQOyMb9SeKqo91Y/O9k9DG9GXaZs88oZdqWcceIMDbKmQoiL4szz2Skl1Rqmzlk13RGrRvsNYjxEFpIraKPnYK52utiu9VeZlAOBPsIUYPilVCYhxFumiOzPYfFXGi47Sk3vdu+3eB+q5mJz6AHkMuBVjIbU43lXcT0QIJ9xJfGjVjSA5XgmyA7oxAma8z2WXPKGnw6FRIb3o9RoytV/TFRueRfEC+4oHHWDINMH11iMOr+H6Ia0owehn3Hubo6uRnWyRzOBpG8jzywbt5jt5gwJRGYzHzDcpJScZiuB2iPmKnoxj6wAi3yhFxTIQwN4AtRhCPU9cIX6XM7TxRM=
11
+ gem: base32-crockford-checksum
12
+ on:
13
+ tags: true
14
+ repo: datacite/base32
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,28 @@
1
+ An implementation of Douglas Crockfords Base32-Encoding in Ruby
2
+
3
+ see <http://www.crockford.com/wrmg/base32.html>
4
+
5
+ Installation
6
+ ============
7
+
8
+ $ gem install base32-crockford
9
+
10
+ Changes
11
+ =======
12
+ 0.2.0 - added optional checksum
13
+ 0.1.0 - rename gem to base32-crockford
14
+ 0.0.2 - ruby 1.9 compatibility
15
+ 0.0.1 - initial release
16
+
17
+ Usage
18
+ =====
19
+
20
+ #!/usr/bin/env ruby
21
+
22
+ require 'base32/crockford'
23
+
24
+ Base32::Crockford.encode(1234) # => "16J"
25
+ Base32::Crockford.encode(100**10, :split=>5, :length=>15) # => "02PQH-TY5NH-H0000"
26
+ Base32::Crockford.decode("2pqh-ty5nh-hoooo") # => 10**100
27
+ Base32::Crockford.encode(1234, checksum: true) # => "16JD"
28
+ Base32::Crockford.decode("16JD", checksum: true) # => 1234
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift './lib'
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'rake/testtask'
7
+ Rake::TestTask.new(:test)
8
+
9
+ task :default => :test
10
+
@@ -0,0 +1,20 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'base32/crockford'
3
+
4
+ spec = Gem::Specification.new do |s|
5
+ s.name = 'base32-crockford-checksum'
6
+ s.version = Base32::Crockford::VERSION
7
+ s.summary = "32-symbol notation for expressing numbers in a form that can be conveniently and accurately transmitted between humans"
8
+
9
+ s.files = `git ls-files`.split("\n")
10
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
11
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+
13
+ s.require_path = 'lib'
14
+ s.author = "Levin Alexander"
15
+ s.homepage = "http://levinalex.net/src/base32"
16
+ s.email = "mail@levinalex.net"
17
+
18
+ s.add_development_dependency 'rake'
19
+ s.add_development_dependency 'test-unit', '~> 3.2.3'
20
+ end
@@ -0,0 +1,158 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # (c) 2008, Levin Alexander <http://levinalex.net>
4
+ #
5
+ # This file is released under the same license as ruby.
6
+
7
+ require 'enumerator'
8
+
9
+ module Base32
10
+ end
11
+
12
+ # encode a value with the encoding defined by _Douglas_ _Crockford_ in
13
+ # <http://www.crockford.com/wrmg/base32.html>
14
+ #
15
+ # this is *not* the same as the Base32 encoding defined in RFC 4648
16
+ #
17
+ #
18
+ # The Base32 symbol set is a superset of the Base16 symbol set.
19
+ #
20
+ # We chose a symbol set of 10 digits and 22 letters. We exclude 4 of the 26
21
+ # letters: I L O U.
22
+ #
23
+ # Excluded Letters
24
+ #
25
+ # I:: Can be confused with 1
26
+ # L:: Can be confused with 1
27
+ # O:: Can be confused with 0
28
+ # U:: Accidental obscenity
29
+ #
30
+ # 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, only upper case
32
+ # letters are used.
33
+ #
34
+ # If the bit-length of the number to be encoded is not a multiple of 5 bits,
35
+ # then zero-extend the number to make its bit-length a multiple of 5.
36
+ #
37
+ # Hyphens (-) can be inserted into symbol strings. This can partition a
38
+ # string into manageable pieces, improving readability by helping to prevent
39
+ # confusion. Hyphens are ignored during decoding. An application may look for
40
+ # hyphens to assure symbol string correctness.
41
+ #
42
+ #
43
+ class Base32::Crockford
44
+ VERSION = "0.2.2"
45
+
46
+ ENCODE_CHARS =
47
+ %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 ?)
48
+
49
+ CHECKSUM_MAP = { "*" => 32, "~" => 33, "$" => 34, "=" => 35, "U" => 36 }
50
+
51
+ DECODE_MAP = ENCODE_CHARS.to_enum(:each_with_index).inject({}) do |h,(c,i)|
52
+ h[c] = i; h
53
+ end.merge({'I' => 1, 'L' => 1, 'O' => 0})
54
+
55
+ # encodes an integer into a string
56
+ #
57
+ # when +checksum+ is given, a checksum is added at the end of the the string,
58
+ # calculated as modulo 37 of +number+. Five additional checksum symbols are
59
+ # used for symbol values 32-36
60
+ #
61
+ # when +split+ is given a hyphen is inserted every <n> characters to improve
62
+ # readability
63
+ #
64
+ # when +length+ is given, the resulting string is zero-padded to be exactly
65
+ # this number of characters long (hyphens are ignored)
66
+ #
67
+ # Base32::Crockford.encode(1234) # => "16J"
68
+ # Base32::Crockford.encode(123456789012345, :split=>5) # => "3G923-0VQVS"
69
+ #
70
+ def self.encode(number, opts = {})
71
+ # verify options
72
+ raise ArgumentError unless (opts.keys - [:length, :split, :checksum] == [])
73
+
74
+ str = number.to_s(2).reverse.scan(/.{1,5}/).map do |bits|
75
+ ENCODE_CHARS[bits.reverse.to_i(2)]
76
+ end.reverse.join
77
+
78
+ str = str + ENCODE_CHARS[number % 37] if opts[:checksum]
79
+
80
+ str = str.rjust(opts[:length], '0') if opts[:length]
81
+
82
+ if opts[:split]
83
+ str = str.reverse
84
+ str = str.scan(/.{1,#{opts[:split]}}/).map { |x| x.reverse }
85
+ str = str.reverse.join("-")
86
+ end
87
+
88
+ str
89
+ end
90
+
91
+ # decode a string to an integer using Douglas Crockfords Base32 Encoding
92
+ #
93
+ # the string is converted to uppercase and hyphens are stripped before
94
+ # decoding
95
+ #
96
+ # I,i,l,L decodes to 1
97
+ # O,o decodes to 0
98
+ #
99
+ # Base32::Crockford.decode("16J") # => 1234
100
+ # Base32::Crockford.decode("OI") # => 1
101
+ # Base32::Crockford.decode("3G923-0VQVS") # => 123456789012345
102
+ #
103
+ # returns +nil+ if the string contains invalid characters and can't be
104
+ # decoded, or if checksum option is used and checksum is incorrect
105
+ #
106
+ 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
111
+
112
+ number = clean(string).split(//).map { |char|
113
+ DECODE_MAP[char] or return nil
114
+ }.inject(0) { |result,val| (result << 5) + val }
115
+
116
+ number % 37 == checksum_number or return nil if opts[:checksum]
117
+
118
+ number
119
+ end
120
+
121
+ # same as decode, but raises ArgumentError when the string can't be decoded
122
+ #
123
+ def self.decode!(string, opts = {})
124
+ decode(string) or raise ArgumentError
125
+ end
126
+
127
+ # return the canonical encoding of a string. converts it to uppercase
128
+ # and removes hyphens
129
+ #
130
+ # replaces invalid characters with a question mark ('?')
131
+ #
132
+ def self.normalize(string, opts = {})
133
+ checksum_char = string.slice!(-1) if opts[:checksum]
134
+
135
+ string = clean(string).split(//).map { |char|
136
+ ENCODE_CHARS[DECODE_MAP[char] || 32]
137
+ }.join
138
+
139
+ string = string + checksum_char if opts[:checksum]
140
+
141
+ string
142
+ end
143
+
144
+ # returns false if the string contains invalid characters and can't be
145
+ # decoded
146
+ #
147
+ def self.valid?(string, opts = {})
148
+ !(normalize(string, opts) =~ /\?/)
149
+ end
150
+
151
+ class << self
152
+ def clean(string)
153
+ string.gsub(/-/,'').upcase
154
+ end
155
+ private :clean
156
+ end
157
+ end
158
+
@@ -0,0 +1,96 @@
1
+ # encoding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'base32/crockford'
5
+
6
+ class TestBase32Crockford < Test::Unit::TestCase
7
+
8
+ def test_encoding_and_decoding_single_chars
9
+ from = (0..31).to_a
10
+ 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)
11
+
12
+ from.zip(to) do |symbol_value, encode_symbol|
13
+ assert_equal encode_symbol, Base32::Crockford.encode(symbol_value)
14
+ assert_equal symbol_value, Base32::Crockford.decode(encode_symbol)
15
+ end
16
+ end
17
+
18
+ def test_encoding_larger_numbers
19
+ assert_equal("10", Base32::Crockford.encode(32))
20
+ assert_equal("16J", Base32::Crockford.encode(1234))
21
+ end
22
+
23
+ def test_decoding_strings
24
+ assert_equal(1234, Base32::Crockford.decode("16J"))
25
+ end
26
+
27
+ def test_decoding_normalizes_symbols
28
+ assert_equal Base32::Crockford.decode('11100110'),
29
+ Base32::Crockford.decode('IL1O0ilo')
30
+ end
31
+
32
+ def test_decoding_lowercase
33
+ assert_equal Base32::Crockford.decode("abcdefghijklmnopqrstvwxyz"),
34
+ Base32::Crockford.decode("ABCDEFGHIJKLMNOPQRSTVWXYZ")
35
+ end
36
+
37
+ def test_decoding_invalid_strings
38
+ assert_equal nil, Base32::Crockford.decode("Ü'+?")
39
+ assert_raises(ArgumentError) { Base32::Crockford.decode!("'+?") }
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_normalize
47
+ assert_equal "HE110W0R1D", Base32::Crockford.normalize("hello-world")
48
+ assert_equal "B?123", Base32::Crockford.normalize("BU-123")
49
+ end
50
+
51
+ def test_normalize_with_checksum
52
+ assert_equal "B?123", Base32::Crockford.normalize("BU-123", :checksum => true)
53
+ assert_equal "B123U", Base32::Crockford.normalize("B123U", :checksum => true)
54
+ end
55
+
56
+ def test_valid
57
+ assert_equal true, Base32::Crockford.valid?("hello-world")
58
+ assert_equal false, Base32::Crockford.valid?("BU-123")
59
+ end
60
+
61
+ def test_valid_with_checksum
62
+ assert_equal true, Base32::Crockford.valid?("B123U", :checksum => true)
63
+ assert_equal false, Base32::Crockford.valid?("BU-123", :checksum => true)
64
+ end
65
+
66
+ def test_length_and_hyphenization
67
+ assert_equal "0016J", Base32::Crockford.encode(1234, :length => 5)
68
+ assert_equal "0-01-6J",
69
+ Base32::Crockford.encode(1234, :length => 5, :split => 2)
70
+ assert_equal "00-010",
71
+ Base32::Crockford.encode(32, :length => 5, :split => 3)
72
+ end
73
+
74
+ def test_encoding_checksum
75
+ assert_equal "16JD",
76
+ Base32::Crockford.encode(1234, :checksum => true)
77
+ assert_equal "016JD",
78
+ Base32::Crockford.encode(1234, :length => 5, :checksum => true)
79
+ assert_equal "0-16-JD",
80
+ Base32::Crockford.encode(1234, :length => 5, :split => 2, :checksum => true)
81
+ end
82
+
83
+ def test_decoding_checksum
84
+ assert_equal 1234,
85
+ Base32::Crockford.decode("16JD", :checksum => true)
86
+ assert_equal 1234,
87
+ Base32::Crockford.decode("016JD", :length => 5, :checksum => true)
88
+ assert_equal 1234,
89
+ Base32::Crockford.decode("0-16-JD", :length => 5, :split => 2, :checksum => true)
90
+ end
91
+
92
+ def test_decoding_invalid_checksum
93
+ assert_equal nil,
94
+ Base32::Crockford.decode("16JC", :checksum => true)
95
+ end
96
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: base32-crockford-checksum
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Levin Alexander
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
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
+ - !ruby/object:Gem::Dependency
28
+ name: test-unit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.2.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.2.3
41
+ description:
42
+ email: mail@levinalex.net
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - ".gitignore"
48
+ - ".travis.yml"
49
+ - Gemfile
50
+ - README.markdown
51
+ - Rakefile
52
+ - base32-crockford-checksum.gemspec
53
+ - lib/base32/crockford.rb
54
+ - test/test_base32_crockford.rb
55
+ homepage: http://levinalex.net/src/base32
56
+ licenses: []
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.4.5
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: 32-symbol notation for expressing numbers in a form that can be conveniently
78
+ and accurately transmitted between humans
79
+ test_files: []