2017-02-10 03:58:45 +03:00
|
|
|
# frozen_string_literal: true
|
2008-09-25 16:24:54 +04:00
|
|
|
#
|
2009-06-03 21:26:35 +04:00
|
|
|
# = base64.rb: methods for base64-encoding and -decoding strings
|
2008-09-25 16:24:54 +04:00
|
|
|
#
|
|
|
|
|
|
|
|
# The Base64 module provides for the encoding (#encode64, #strict_encode64,
|
|
|
|
# #urlsafe_encode64) and decoding (#decode64, #strict_decode64,
|
|
|
|
# #urlsafe_decode64) of binary data using a Base64 representation.
|
|
|
|
#
|
|
|
|
# == Example
|
|
|
|
#
|
2009-03-06 06:56:38 +03:00
|
|
|
# A simple encoding and decoding.
|
|
|
|
#
|
2008-09-25 16:24:54 +04:00
|
|
|
# require "base64"
|
|
|
|
#
|
|
|
|
# enc = Base64.encode64('Send reinforcements')
|
2009-03-06 06:56:38 +03:00
|
|
|
# # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
|
2008-09-25 16:24:54 +04:00
|
|
|
# plain = Base64.decode64(enc)
|
|
|
|
# # -> "Send reinforcements"
|
|
|
|
#
|
|
|
|
# The purpose of using base64 to encode data is that it translates any
|
|
|
|
# binary data into purely printable characters.
|
|
|
|
|
|
|
|
module Base64
|
|
|
|
module_function
|
|
|
|
|
|
|
|
# Returns the Base64-encoded version of +bin+.
|
|
|
|
# This method complies with RFC 2045.
|
2013-05-19 07:10:21 +04:00
|
|
|
# Line feeds are added to every 60 encoded characters.
|
2008-09-25 16:24:54 +04:00
|
|
|
#
|
|
|
|
# require 'base64'
|
|
|
|
# Base64.encode64("Now is the time for all good coders\nto learn Ruby")
|
|
|
|
#
|
|
|
|
# <i>Generates:</i>
|
|
|
|
#
|
|
|
|
# Tm93IGlzIHRoZSB0aW1lIGZvciBhbGwgZ29vZCBjb2RlcnMKdG8gbGVhcm4g
|
|
|
|
# UnVieQ==
|
|
|
|
def encode64(bin)
|
|
|
|
[bin].pack("m")
|
|
|
|
end
|
|
|
|
|
|
|
|
# Returns the Base64-decoded version of +str+.
|
|
|
|
# This method complies with RFC 2045.
|
|
|
|
# Characters outside the base alphabet are ignored.
|
|
|
|
#
|
|
|
|
# require 'base64'
|
|
|
|
# str = 'VGhpcyBpcyBsaW5lIG9uZQpUaGlzIG' +
|
|
|
|
# 'lzIGxpbmUgdHdvClRoaXMgaXMgbGlu' +
|
|
|
|
# 'ZSB0aHJlZQpBbmQgc28gb24uLi4K'
|
|
|
|
# puts Base64.decode64(str)
|
|
|
|
#
|
|
|
|
# <i>Generates:</i>
|
|
|
|
#
|
|
|
|
# This is line one
|
|
|
|
# This is line two
|
|
|
|
# This is line three
|
|
|
|
# And so on...
|
|
|
|
def decode64(str)
|
2017-02-10 03:58:47 +03:00
|
|
|
str.unpack1("m")
|
2008-09-25 16:24:54 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Returns the Base64-encoded version of +bin+.
|
|
|
|
# This method complies with RFC 4648.
|
|
|
|
# No line feeds are added.
|
|
|
|
def strict_encode64(bin)
|
|
|
|
[bin].pack("m0")
|
|
|
|
end
|
|
|
|
|
|
|
|
# Returns the Base64-decoded version of +str+.
|
|
|
|
# This method complies with RFC 4648.
|
|
|
|
# ArgumentError is raised if +str+ is incorrectly padded or contains
|
|
|
|
# non-alphabet characters. Note that CR or LF are also rejected.
|
|
|
|
def strict_decode64(str)
|
2017-02-10 03:58:47 +03:00
|
|
|
str.unpack1("m0")
|
2008-09-25 16:24:54 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Returns the Base64-encoded version of +bin+.
|
|
|
|
# This method complies with ``Base 64 Encoding with URL and Filename Safe
|
|
|
|
# Alphabet'' in RFC 4648.
|
|
|
|
# The alphabet uses '-' instead of '+' and '_' instead of '/'.
|
2015-02-13 15:31:30 +03:00
|
|
|
# Note that the result can still contain '='.
|
2015-05-20 17:24:58 +03:00
|
|
|
# You can remove the padding by setting +padding+ as false.
|
2015-02-13 15:31:30 +03:00
|
|
|
def urlsafe_encode64(bin, padding: true)
|
|
|
|
str = strict_encode64(bin).tr("+/", "-_")
|
|
|
|
str = str.delete("=") unless padding
|
|
|
|
str
|
2008-09-25 16:24:54 +04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Returns the Base64-decoded version of +str+.
|
|
|
|
# This method complies with ``Base 64 Encoding with URL and Filename Safe
|
|
|
|
# Alphabet'' in RFC 4648.
|
|
|
|
# The alphabet uses '-' instead of '+' and '_' instead of '/'.
|
2015-02-13 15:31:30 +03:00
|
|
|
#
|
|
|
|
# The padding character is optional.
|
|
|
|
# This method accepts both correctly-padded and unpadded input.
|
|
|
|
# Note that it still rejects incorrectly-padded input.
|
2008-09-25 16:24:54 +04:00
|
|
|
def urlsafe_decode64(str)
|
2015-02-13 15:31:30 +03:00
|
|
|
# NOTE: RFC 4648 does say nothing about unpadded input, but says that
|
|
|
|
# "the excess pad characters MAY also be ignored", so it is inferred that
|
|
|
|
# unpadded input is also acceptable.
|
|
|
|
str = str.tr("-_", "+/")
|
|
|
|
if !str.end_with?("=") && str.length % 4 != 0
|
|
|
|
str = str.ljust((str.length + 3) & ~3, "=")
|
|
|
|
end
|
|
|
|
strict_decode64(str)
|
2008-09-25 16:24:54 +04:00
|
|
|
end
|
|
|
|
end
|