Bre*_*ent 14 ruby base64 character-encoding
查看Ruby的Base64.encode的源代码在Base64中编码该数据之前,我无法确定字符串转换为什么字符编码(如果有的话).在Base64中编码的Utf-8字符串将与在Base64中编码的Utf-16字符串有很大不同.Ruby是否会对此操作做出任何承诺?
Vic*_*lis 29
在base64中编码和解码utf-8字符串的示例:
text = "intérnalionálização"
=> "intérnalionálização"
text.encoding
=> #<Encoding:UTF-8>
encoded = Base64.encode64(text)
=> "aW50w6lybmFsaW9uw6FsaXphw6fDo28=\n"
encoded.encoding
=> #<Encoding:US-ASCII>
decoded = Base64.decode64(encode)
=> "int\xC3\xA9rnalion\xC3\xA1liza\xC3\xA7\xC3\xA3o"
decoded.encoding
=> #<Encoding:US-ASCII>
decoded = decoded.force_encoding('UTF-8')
=> "intérnalionálização"
decoded.encoding
=> #<Encoding:UTF-8>
Run Code Online (Sandbox Code Playgroud)
mu *_*ort 11
该精细的手工有这样一段话:
encode64(bin)
返回bin64的Base64编码版本.此方法符合RFC 2045.
RFC 2045的第6.8节说:
6.8.Base64内容传输编码
Base64内容传输编码旨在以不需要人类可读的形式表示任意八位字节序列.[...]
使用65个字符的US-ASCII子集,每个可打印字符可以表示6位.(额外的第65个字符"="用于表示特殊处理功能.)
所以Base64将字节编码为ASCII.如果这些字节实际上代表UTF-8编码的字符串,则UTF-8字符串将被分解为单个字节,并且这些字节将被转换为Base64; 例如,如果你有一个UTF-8字符串,'µ'那么你最终会将字节0xc2和0xb5(按此顺序)编码为Base64表示"wrU=\n".如果你开始使用二进制字符串"\xc2\xb5"(恰好匹配UTF-8版本'µ'),那么你将获得相同的"wrU=\n"输出.
当您解码时"wrU=\n",您将获得字节"\xc2\xb5",您必须知道这些字节应该是UTF-8编码的文本,而不是某些任意blob的位.这就是为什么你有单独的内容类型和字符集元数据附加到Base64.
类似地,如果你有一个UTF-16字符串,那么它将被分成字节,这些字节将被编码,就像任何其他字节字符串一样.当然,由于字节顺序问题,这种情况稍微复杂一些,但这就是为什么我们有内容类型和字符集标题和BOM.
重点是Base64使用字节而不是字符.什么格式(UTF-8文本,UTF-16文本,PNG图像......)是别人的问题.Base64只是将字节流转换为US ASCII的子集,然后再转换为字节; 必须单独指定这些字节的格式.
我在源头做了一些探讨,结果可能会引起人们的兴趣,即使它们并不完全相关.该encode64方法很简单:
def encode64(bin)
[bin].pack("m")
end
Run Code Online (Sandbox Code Playgroud)
然后,如果你看看Array#pack:
static VALUE
pack_pack(VALUE ary, VALUE fmt)
{
/*...*/
int enc_info = 1; /* 0 - BINARY, 1 - US-ASCII, 2 - UTF-8 */
Run Code Online (Sandbox Code Playgroud)
并且密切关注enc_info,你会发现一个'm'格式将不再enc_info存在,因此打包的字符串将以US-ASCII形式出现,因此encode64将按预期产生US ASCII输出.
| 归档时间: |
|
| 查看次数: |
14868 次 |
| 最近记录: |