base32-crockford 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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