base64_compatible 0.0.1
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.
- 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
|
+
|