模块 Base64

模块 Base64 提供了以下方法:

  • 将二进制字符串(包含非 ASCII 字符)编码为可打印的 ASCII 字符字符串。

  • 解码这种编码的字符串。

Base64 通常用于不允许或不支持二进制数据的场合

  • HTML 或 CSS 文件中的图像,或 URL 中。

  • 电子邮件附件。

Base64 编码的字符串比其源字符串大约大三分之一。有关更多信息,请参阅 维基百科文章

此模块提供三对编码/解码方法。您在这些方法中的选择应取决于:

  • 用于编码和解码的字符集。

  • 是否使用“填充”。

  • 编码的字符串是否包含换行符。

注意:此页面上的示例假设包含程序已执行

require 'base64'

编码字符集

Base64 编码的字符串仅包含来自 64 个字符集的字符:

  • ('A'..'Z').

  • ('a'..'z').

  • ('0'..'9').

  • =,即 “填充” 字符。

  • 以及以下两者之一:

如果您正在处理来自或放入 URL 的 Base64 编码的字符串,则应选择符合 RFC-4648 标准的这对编码器-解码器方法:

否则,您可以选择此模块中的任何一对,包括上面的这对,或符合 RFC-2045 标准的对:

填充

Base64 编码将三个输入字节更改为四个输出字符。

编码方法中的填充

填充 – 使用零个、一个或两个尾随 = 字符扩展编码的字符串 – 由方法 Base64.encode64Base64.strict_encode64 和默认情况下 Base64.urlsafe_encode64 执行。

Base64.encode64('s')                         # => "cw==\n"
Base64.strict_encode64('s')                  # => "cw=="
Base64.urlsafe_encode64('s')                 # => "cw=="
Base64.urlsafe_encode64('s', padding: false) # => "cw"

执行填充时,编码的字符串的长度始终为 4n,其中 n 是非负整数。

  • 长度为 3n 的输入字节生成长度为 4n 的未填充输出字符。

    # n = 1:  3 bytes => 4 characters.
    Base64.strict_encode64('123')      # => "MDEy"
    # n = 2:  6 bytes => 8 characters.
    Base64.strict_encode64('123456')   # => "MDEyMzQ1"
    
  • 长度为 3n+1 的输入字节生成长度为 4(n+1) 的填充输出字符,末尾有两个填充字符。

    # n = 1:  4 bytes => 8 characters.
    Base64.strict_encode64('1234')     # => "MDEyMw=="
    # n = 2:  7 bytes => 12 characters.
    Base64.strict_encode64('1234567')  # => "MDEyMzQ1Ng=="
    
  • 长度为 3n+2 的输入字节生成长度为 4(n+1) 的填充输出字符,末尾有一个填充字符。

    # n = 1:  5 bytes => 8 characters.
    Base64.strict_encode64('12345')    # => "MDEyMzQ="
    # n = 2:  8 bytes => 12 characters.
    Base64.strict_encode64('12345678') # => "MDEyMzQ1Njc="
    

当抑制填充时,对于正整数 n

  • 长度为 3n 的输入字节生成长度为 4n 的未填充输出字符。

    # n = 1:  3 bytes => 4 characters.
    Base64.urlsafe_encode64('123', padding: false)      # => "MDEy"
    # n = 2:  6 bytes => 8 characters.
    Base64.urlsafe_encode64('123456', padding: false)   # => "MDEyMzQ1"
    
  • 长度为 3n+1 的输入字节生成长度为 4n+2 的未填充输出字符,末尾有两个填充字符。

    # n = 1:  4 bytes => 6 characters.
    Base64.urlsafe_encode64('1234', padding: false)     # => "MDEyMw"
    # n = 2:  7 bytes => 10 characters.
    Base64.urlsafe_encode64('1234567', padding: false)  # => "MDEyMzQ1Ng"
    
  • 长度为 3n+2 的输入字节生成长度为 4n+3 的未填充输出字符,末尾有一个填充字符。

    # n = 1:  5 bytes => 7 characters.
    Base64.urlsafe_encode64('12345', padding: false)    # => "MDEyMzQ"
    # m = 2:  8 bytes => 11 characters.
    Base64.urlsafe_encode64('12345678', padding: false) # => "MDEyMzQ1Njc"
    

解码方法中的填充

所有 Base64 解码方法都支持(但不要求)填充。

方法 Base64.decode64 不检查填充的大小。

Base64.decode64("MDEyMzQ1Njc") # => "01234567"
Base64.decode64("MDEyMzQ1Njc=") # => "01234567"
Base64.decode64("MDEyMzQ1Njc==") # => "01234567"

方法 Base64.strict_decode64 严格执行填充大小。

Base64.strict_decode64("MDEyMzQ1Njc")   # Raises ArgumentError
Base64.strict_decode64("MDEyMzQ1Njc=")  # => "01234567"
Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError

方法 Base64.urlsafe_decode64 允许 str 中的填充,如果存在,则必须正确:请参阅上面的 填充

Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567"
Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError.

换行符

Base64.encode64Base64.urlsafe_encode64 返回的编码字符串在每个 60 个字符的序列之后以及(如果非空)末尾都有一个嵌入的换行符。

# No newline if empty.
encoded = Base64.encode64("\x00" *  0)
encoded.index("\n") # => nil

# Newline at end of short output.
encoded = Base64.encode64("\x00" *  1)
encoded.size        # => 4
encoded.index("\n") # => 4

# Newline at end of longer output.
encoded = Base64.encode64("\x00" * 45)
encoded.size        # => 60
encoded.index("\n") # => 60

# Newlines embedded and at end of still longer output.
encoded = Base64.encode64("\x00" * 46)
encoded.size                          # => 65
encoded.rindex("\n")                  # => 65
encoded.split("\n").map {|s| s.size } # => [60, 4]

要编码的字符串本身可能包含换行符,这些换行符将编码为 Base64。

  #   Base64.encode64("\n\n\n") # => "CgoK\n"
s = "This is line 1\nThis is line 2\n"
Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"

常量

VERSION

公共实例方法

decode64(str) 点击以切换源

返回一个包含对符合 RFC-2045 标准的 Base64 编码字符串 str 进行解码的字符串。

s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
Base64.decode64(s) # => "This is line 1\nThis is line 2\n"

str 中的非 Base64 字符将被忽略;请参阅上面的 编码字符集:这些字符包括换行符和字符 -/

Base64.decode64("\x00\n-_") # => ""

str 中的填充(即使不正确)也会被忽略。

Base64.decode64("MDEyMzQ1Njc")   # => "01234567"
Base64.decode64("MDEyMzQ1Njc=")  # => "01234567"
Base64.decode64("MDEyMzQ1Njc==") # => "01234567"
# File base64-0.2.0/lib/base64.rb, line 241
def decode64(str)
  str.unpack1("m")
end
encode64(bin) 点击以切换源

返回一个包含 bin 的符合 RFC-2045 标准的 Base64 编码的字符串。

根据 RFC 2045,返回的字符串可能包含 URL 不安全的字符 +/;请参阅上面的 编码字符集

Base64.encode64("\xFB\xEF\xBE") # => "++++\n"
Base64.encode64("\xFF\xFF\xFF") # => "////\n"

返回的字符串可能包含填充;请参阅上面的 填充

Base64.encode64('*') # => "Kg==\n"

返回的字符串以换行符结尾,如果足够长,则会有一个或多个嵌入的换行符;请参阅上面的 换行符

Base64.encode64('*') # => "Kg==\n"
Base64.encode64('*' * 46)
# => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq\nKg==\n"

要编码的字符串本身可能包含换行符,这些换行符将编码为普通的 Base64。

Base64.encode64("\n\n\n") # => "CgoK\n"
s = "This is line 1\nThis is line 2\n"
Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n"
# File base64-0.2.0/lib/base64.rb, line 219
def encode64(bin)
  [bin].pack("m")
end
strict_decode64(str) 点击以切换源

返回一个包含对符合 RFC-2045 标准的 Base64 编码字符串 str 进行解码的字符串。

s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
Base64.strict_decode64(s) # => "This is line 1\nThis is line 2\n"

不允许 str 中出现非 Base64 字符;请参阅上面的 编码字符集:这些字符包括换行符和字符 -/

Base64.strict_decode64("\n") # Raises ArgumentError
Base64.strict_decode64('-')  # Raises ArgumentError
Base64.strict_decode64('_')  # Raises ArgumentError

如果 str 中存在填充,则必须正确。

Base64.strict_decode64("MDEyMzQ1Njc")   # Raises ArgumentError
Base64.strict_decode64("MDEyMzQ1Njc=")  # => "01234567"
Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError
# File base64-0.2.0/lib/base64.rb, line 297
def strict_decode64(str)
  str.unpack1("m0")
end
strict_encode64(bin) 点击以切换源

返回一个包含 bin 的符合 RFC-2045 标准的 Base64 编码的字符串。

根据 RFC 2045,返回的字符串可能包含 URL 不安全的字符 +/;请参阅上面的 编码字符集

Base64.strict_encode64("\xFB\xEF\xBE") # => "++++\n"
Base64.strict_encode64("\xFF\xFF\xFF") # => "////\n"

返回的字符串可能包含填充;请参阅上面的 填充

Base64.strict_encode64('*') # => "Kg==\n"

返回的字符串将不包含换行符,无论其长度如何;请参阅上面的 换行符

Base64.strict_encode64('*') # => "Kg=="
Base64.strict_encode64('*' * 46)
# => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg=="

要编码的字符串本身可能包含换行符,这些换行符将编码为普通的 Base64。

Base64.strict_encode64("\n\n\n") # => "CgoK"
s = "This is line 1\nThis is line 2\n"
Base64.strict_encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK"
# File base64-0.2.0/lib/base64.rb, line 273
def strict_encode64(bin)
  [bin].pack("m0")
end
urlsafe_decode64(str) 点击以切换源

返回对符合 RFC-4648 标准的 Base64 编码字符串 str 进行解码的结果。

str 可能不包含非 Base64 字符;请参阅上面的 编码字符集

Base64.urlsafe_decode64('+')  # Raises ArgumentError.
Base64.urlsafe_decode64('/')  # Raises ArgumentError.
Base64.urlsafe_decode64("\n") # Raises ArgumentError.

如果 str 中存在填充,则必须正确:请参阅上面的 填充

Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567"
Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567"
Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError.
# File base64-0.2.0/lib/base64.rb, line 351
def urlsafe_decode64(str)
  # 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.
  if !str.end_with?("=") && str.length % 4 != 0
    str = str.ljust((str.length + 3) & ~3, "=")
    str.tr!("-_", "+/")
  else
    str = str.tr("-_", "+/")
  end
  strict_decode64(str)
end
urlsafe_encode64(bin, padding: true) 点击以切换源

返回 bin 的符合 RFC-4648 标准的 Base64 编码。

根据 RFC 4648,返回的字符串将不包含 URL 不安全的字符 +/,而是可能包含 URL 安全的字符 -_;请参阅上面的 编码字符集

Base64.urlsafe_encode64("\xFB\xEF\xBE") # => "----"
Base64.urlsafe_encode64("\xFF\xFF\xFF") # => "____"

默认情况下,返回的字符串可能包含填充;请参阅上面的 填充

Base64.urlsafe_encode64('*') # => "Kg=="

可以选择抑制填充。

Base64.urlsafe_encode64('*', padding: false) # => "Kg"

返回的字符串将不包含换行符,无论其长度如何;请参阅上面的 换行符

Base64.urlsafe_encode64('*') # => "Kg=="
Base64.urlsafe_encode64('*' * 46)
# => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg=="
# File base64-0.2.0/lib/base64.rb, line 328
def urlsafe_encode64(bin, padding: true)
  str = strict_encode64(bin)
  str.chomp!("==") or str.chomp!("=") unless padding
  str.tr!("+/", "-_")
  str
end