#!/usr/bin/env ruby
module Base64
extend self
CHAR_MAP = Hash[(0..25).map { |i| [[i,(65+i).chr], [i+26, (97+i).chr]] }.flatten(1) + (0..9).map { |i| [i+52, i.to_s] } + [[62,'+'], [63,'/']]]
def encode(input)
result = input.bytes.each_slice(3).map do |a, b, c|
r1 = a >> 2
if b.nil?
r2 = ((a & 3) << 4)
CHAR_MAP.values_at(r1, r2) + ['=', '=']
elsif c.nil?
r2 = ((a & 3) << 4) + (b >> 4)
r3 = ((b & 15) << 2)
CHAR_MAP.values_at(r1, r2, r3) << '='
else
r2 = ((a & 3) << 4) + (b >> 4)
r3 = ((b & 15) << 2) + (c >> 6)
r4 = c & 63
CHAR_MAP.values_at(r1, r2, r3, r4)
end
end.flatten.join
end
end
tests = {
'any carnal pleasure.' => 'YW55IGNhcm5hbCBwbGVhc3VyZS4=',
'any carnal pleasure' => 'YW55IGNhcm5hbCBwbGVhc3VyZQ==',
'any carnal pleasur' => 'YW55IGNhcm5hbCBwbGVhc3Vy',
'any carnal pleasu' => 'YW55IGNhcm5hbCBwbGVhc3U=',
'any carnal pleas' => 'YW55IGNhcm5hbCBwbGVhcw==',
}
tests.each do |origin, encoded|
unless Base64.encode(origin) == encoded
raise "failed: expecting
#{encoded}
got
#{Base64.encode(origin)}
"
end
end
puts "success"