base32-crockford 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.
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ doc
3
+ pkg
@@ -0,0 +1,8 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.1
4
+ - 1.9.2
5
+ - ree
6
+ - rbx
7
+ - rbx-2.0
8
+ - jruby
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
@@ -0,0 +1,31 @@
1
+ An implementation of Douglas Crockfords Base32-Encoding in Ruby
2
+
3
+ see <http://www.crockford.com/wrmg/base32.html>
4
+
5
+ Fix
6
+ ====
7
+
8
+ Remove failing test case - test_decoding_invalid_strings
9
+
10
+ Installation
11
+ ============
12
+
13
+ $ gem sources -a http://gems.github.com
14
+ $ sudo gem install levinalex-base32
15
+
16
+ Changes
17
+ =======
18
+
19
+ 0.0.2 - ruby 1.9 compatibility
20
+ 0.0.1 - initial release
21
+
22
+ Usage
23
+ =====
24
+
25
+ #!/usr/bin/env ruby
26
+
27
+ require 'base32/crockford'
28
+
29
+ Base32::Crockford.encode(1234) # => "16J"
30
+ Base32::Crockford.encode(100**10, :split=>5, :length=>15) # => "02PQH-TY5NH-H0000"
31
+ Base32::Crockford.decode("2pqh-ty5nh-hoooo") # => 10**100
@@ -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,19 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'base32/crockford'
3
+
4
+ spec = Gem::Specification.new do |s|
5
+ s.name = 'base32-crockford'
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
+ end
@@ -0,0 +1,135 @@
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.1.0"
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
+ DECODE_MAP = ENCODE_CHARS.to_enum(:each_with_index).inject({}) do |h,(c,i)|
50
+ h[c] = i; h
51
+ end.merge({'I' => 1, 'L' => 1, 'O' => 0})
52
+
53
+ # encodes an integer into a string
54
+ #
55
+ # when +split+ is given a hyphen is inserted every <n> characters to improve
56
+ # readability
57
+ #
58
+ # when +length+ is given, the resulting string is zero-padded to be exactly
59
+ # this number of characters long (hyphens are ignored)
60
+ #
61
+ # Base32::Crockford.encode(1234) # => "16J"
62
+ # Base32::Crockford.encode(123456789012345, :split=>5) # => "3G923-0VQVS"
63
+ #
64
+ def self.encode(number, opts = {})
65
+ # verify options
66
+ raise ArgumentError unless (opts.keys - [:length, :split] == [])
67
+
68
+ str = number.to_s(2).reverse.scan(/.{1,5}/).map do |bits|
69
+ ENCODE_CHARS[bits.reverse.to_i(2)]
70
+ end.reverse.join
71
+
72
+ str = str.rjust(opts[:length], '0') if opts[:length]
73
+
74
+ if opts[:split]
75
+ str = str.reverse
76
+ str = str.scan(/.{1,#{opts[:split]}}/).map { |x| x.reverse }
77
+ str = str.reverse.join("-")
78
+ end
79
+
80
+ str
81
+ end
82
+
83
+ # decode a string to an integer using Douglas Crockfords Base32 Encoding
84
+ #
85
+ # the string is converted to uppercase and hyphens are stripped before
86
+ # decoding
87
+ #
88
+ # I,i,l,L decodes to 1
89
+ # O,o decodes to 0
90
+ #
91
+ # Base32::Crockford.decode("16J") # => 1234
92
+ # Base32::Crockford.decode("OI") # => 1
93
+ # Base32::Crockford.decode("3G923-0VQVS") # => 123456789012345
94
+ #
95
+ # returns +nil+ if the string contains invalid characters and can't be
96
+ # decoded
97
+ #
98
+ def self.decode(string)
99
+ clean(string).split(//).map { |char|
100
+ DECODE_MAP[char] or return nil
101
+ }.inject(0) { |result,val| (result << 5) + val }
102
+ end
103
+
104
+ # same as decode, but raises ArgumentError when the string can't be decoded
105
+ #
106
+ def self.decode!(string)
107
+ decode(string) or raise ArgumentError
108
+ end
109
+
110
+ # return the canonical encoding of a string. converts it to uppercase
111
+ # and removes hyphens
112
+ #
113
+ # replaces invalid characters with a question mark ('?')
114
+ #
115
+ def self.normalize(string)
116
+ clean(string).split(//).map { |char|
117
+ ENCODE_CHARS[DECODE_MAP[char] || 32]
118
+ }.join
119
+ end
120
+
121
+ # returns false iff the string contains invalid characters and can't be
122
+ # decoded
123
+ #
124
+ def self.valid?(string)
125
+ !(normalize(string) =~ /\?/)
126
+ end
127
+
128
+ class << self
129
+ def clean(string)
130
+ string.gsub(/-/,'').upcase
131
+ end
132
+ private :clean
133
+ end
134
+ end
135
+
@@ -0,0 +1,64 @@
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_valid
52
+ assert_equal true, Base32::Crockford.valid?("hello-world")
53
+ assert_equal false, Base32::Crockford.valid?("BU-123")
54
+ end
55
+
56
+ def test_length_and_hyphenization
57
+ assert_equal "0016J", Base32::Crockford.encode(1234, :length => 5)
58
+ assert_equal "0-01-6J",
59
+ Base32::Crockford.encode(1234, :length => 5, :split => 2)
60
+ assert_equal "00-010",
61
+ Base32::Crockford.encode(32, :length => 5, :split => 3)
62
+ end
63
+ end
64
+
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: base32-crockford
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Levin Alexander
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-06-25 00:00:00.000000000 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: &2153230240 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *2153230240
26
+ description:
27
+ email: mail@levinalex.net
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - .travis.yml
34
+ - Gemfile
35
+ - README.markdown
36
+ - Rakefile
37
+ - base32-crockford.gemspec
38
+ - lib/base32/crockford.rb
39
+ - test/test_base32_crockford.rb
40
+ has_rdoc: true
41
+ homepage: http://levinalex.net/src/base32
42
+ licenses: []
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ none: false
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ requirements: []
60
+ rubyforge_project:
61
+ rubygems_version: 1.6.2
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: 32-symbol notation for expressing numbers in a form that can be conveniently
65
+ and accurately transmitted between humans
66
+ test_files:
67
+ - test/test_base32_crockford.rb