base64_compatible 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +26 -0
- data/lib/base64_compatible.rb +53 -0
- data/test/base.rb +4 -0
- data/test/strings.rb +17 -0
- data/test/test_coding.rb +37 -0
- metadata +59 -0
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.test_files = FileList['test/test*.rb']
|
6
|
+
t.verbose = true
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "benchmark"
|
10
|
+
task :benchmark do |b|
|
11
|
+
require 'base64'
|
12
|
+
require 'benchmark'
|
13
|
+
require 'lib/base64_compatible'
|
14
|
+
require 'test/strings'
|
15
|
+
include Strings
|
16
|
+
|
17
|
+
n = 5000
|
18
|
+
encoded_login_string = Base64Compatible.encode64(LOGIN_STRING)
|
19
|
+
puts ""
|
20
|
+
Benchmark.bm do |x|
|
21
|
+
x.report("Base64.encode64") { n.times do; Base64.encode64(LOGIN_STRING); end }
|
22
|
+
x.report("Base64Compatible.encode64") { n.times do ; Base64Compatible.encode64(LOGIN_STRING); end }
|
23
|
+
x.report("Base64.decode64") { n.times do; Base64.decode64(encoded_login_string); end }
|
24
|
+
x.report("Base64Compatible.decode64") { n.times do ; Base64Compatible.decode64(encoded_login_string); end }
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Base64Compatible
|
2
|
+
module_function
|
3
|
+
CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split ''
|
4
|
+
|
5
|
+
VERSION = "0.0.1"
|
6
|
+
|
7
|
+
# === Encode Non-MIME
|
8
|
+
# convert string to binary
|
9
|
+
# copy groups of 8 bits to 6 bits
|
10
|
+
# add Base64Compatible padding - 0 fill (to 6) the right side of the last bit grouping
|
11
|
+
# add byte padding (1.8 + 1.9 compat)
|
12
|
+
def encode64(string="")
|
13
|
+
encoded, buffer = '', string.unpack('B*')[0]
|
14
|
+
buffer.scan(/.{6}/).each { |nib| encoded << CHARS[nib.to_i(2)] }
|
15
|
+
encoded << CHARS[((buffer[-(buffer.size % 6)..-1] << "00000")[/^(.{6})(.+)/,1]).to_i(2)]
|
16
|
+
(string.send((string.respond_to?(:bytesize) ? :bytesize : :size)) % 4).times { encoded << '=' }
|
17
|
+
encoded
|
18
|
+
end
|
19
|
+
|
20
|
+
# === Decode MIME and non-MIME
|
21
|
+
# iterate string as character array
|
22
|
+
# left pad each 6 bit representation with 0s
|
23
|
+
# lop off trailing 0s (from encoded fill)
|
24
|
+
# covert decoded bits to new character set
|
25
|
+
def decode64(string="")
|
26
|
+
decoded = ""
|
27
|
+
string.unpack('C*').each do |char_num|
|
28
|
+
base64_index = CHARS.index(char_num.chr)
|
29
|
+
decoded << "%06d" % base64_index.to_s(2) if base64_index
|
30
|
+
end
|
31
|
+
(decoded.size % 8).times { decoded.chop! }
|
32
|
+
decoded.gsub!(/(.{8})/) { |b| b.to_i(2).chr }
|
33
|
+
end
|
34
|
+
|
35
|
+
# TODO: Rework placeholders
|
36
|
+
# def strict_encode64(bin)
|
37
|
+
#
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# def strict_decode64(str)
|
41
|
+
#
|
42
|
+
# end
|
43
|
+
|
44
|
+
# TODO: Replace encode with strict versions to duplicate native lib kaboom
|
45
|
+
def urlsafe_encode64(bin)
|
46
|
+
encode64(bin).tr("+/", "-_")
|
47
|
+
end
|
48
|
+
|
49
|
+
def urlsafe_decode64(str)
|
50
|
+
decode64(str.tr("-_", "+/"))
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/test/base.rb
ADDED
data/test/strings.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Strings
|
2
|
+
LOGIN_STRING = "username:password"
|
3
|
+
STRING = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
|
4
|
+
PARAGRAPH = %Q[
|
5
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
6
|
+
Fusce dolor massa, tincidunt eu pulvinar id, congue vel lacus.
|
7
|
+
Ut at nisi volutpat elit consequat facilisis.
|
8
|
+
Nam imperdiet fringilla urna, ut ultricies tellus hendrerit sed.
|
9
|
+
Sed eleifend velit ut enim ultrices tincidunt.
|
10
|
+
Cras non eros augue, non posuere nibh. Vivamus sit amet nisl magna, eu blandit ante.
|
11
|
+
Curabitur nec magna eget nibh porttitor congue vel sed felis.
|
12
|
+
Phasellus vitae consectetur purus. Curabitur luctus tortor ac nisl lobortis imperdiet.
|
13
|
+
Integer eu pharetra mi. Aenean luctus nibh et est iaculis vehicula.
|
14
|
+
Nunc dictum accumsan urna, vitae auctor nisl consequat ut. Donec at tortor dolor,
|
15
|
+
varius placerat libero. Donec consequat pulvinar urna, non posuere libero tempor at.
|
16
|
+
]
|
17
|
+
end
|
data/test/test_coding.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
require 'strings'
|
3
|
+
require 'base64' # compare with
|
4
|
+
|
5
|
+
class TC_Base64Compatible < Test::Unit::TestCase
|
6
|
+
include Strings
|
7
|
+
|
8
|
+
def test_encode_and_decode
|
9
|
+
assert_equal LOGIN_STRING, Base64Compatible.decode64(Base64Compatible.encode64(LOGIN_STRING))
|
10
|
+
assert_equal STRING, Base64Compatible.decode64(Base64Compatible.encode64(STRING))
|
11
|
+
assert_equal PARAGRAPH, Base64Compatible.decode64(Base64Compatible.encode64(PARAGRAPH))
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_encode_is_non_mime
|
15
|
+
# \n is a MIME marker
|
16
|
+
assert (Base64Compatible.encode64(PARAGRAPH)[/\n/].nil?)
|
17
|
+
# Base64 encodes mime...verify our output doesn't match
|
18
|
+
assert_not_equal Base64.encode64(PARAGRAPH), Base64Compatible.encode64(PARAGRAPH)
|
19
|
+
end
|
20
|
+
|
21
|
+
# NOTE: Depending on byte alignment, codings can be equal.
|
22
|
+
# One example is the included STRING test, where PARAGRAPH wouldn't
|
23
|
+
# show the same result.
|
24
|
+
# assert_equal PARAGRAPH, Base64.decode64(Base64Compatible.encode64(PARAGRAPH)) #=> true
|
25
|
+
def test_base64_std_lib_fails_decoding_non_mime
|
26
|
+
# Base64 can't decode non-MIME encoded base64
|
27
|
+
assert_not_equal STRING, Base64::decode64(Base64Compatible.encode64(STRING))
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_can_decode_base64_std_lib
|
31
|
+
# decode works on MIME encoded base64
|
32
|
+
assert_equal LOGIN_STRING, Base64Compatible.decode64(Base64.encode64(LOGIN_STRING))
|
33
|
+
assert_equal STRING, Base64Compatible.decode64(Base64.encode64(STRING))
|
34
|
+
assert_equal PARAGRAPH, Base64Compatible.decode64(Base64.encode64(PARAGRAPH))
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: base64_compatible
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alan Da Costa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-09 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Standards compliant port of ruby std lib Base64
|
17
|
+
email: alandacosta@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- Rakefile
|
26
|
+
- lib/base64_compatible.rb
|
27
|
+
- test/base.rb
|
28
|
+
- test/strings.rb
|
29
|
+
- test/test_coding.rb
|
30
|
+
has_rdoc: true
|
31
|
+
homepage: http://github.com/adacosta/base64_compatible
|
32
|
+
licenses: []
|
33
|
+
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
|
37
|
+
require_paths:
|
38
|
+
- lib
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
requirements: []
|
52
|
+
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 1.3.5
|
55
|
+
signing_key:
|
56
|
+
specification_version: 3
|
57
|
+
summary: A non-MIME ruby base64 library
|
58
|
+
test_files: []
|
59
|
+
|