编码与 Ruby

Encoding & Encode

常见问题

* 乱码的问题

* Ruby 中 Unable to convert "\x89" from ASCII-8BIT to UTF8

*Incompatible character encodings: ASCII-8BIT and UTF-8

….

基本概念

什么是码表


这个是 “莫尔斯电码

按照一定规则将 XX -> YY 的所形成的表.
(通俗点哈)

基本概念

ASCII 码表 (Wiki)

ASCII 码: 0010 0000 是 “空格” 的 ASCII 码

基本概念

计算机存储的二进制

基本概念

Encoding(编码): 文件 a 使用的是 ISO8859-1 编码. 名词 [使用某一个码表进行字符映射]

Encode(编码): 字母 a 是使用 ISO8859-1 编码进行编码的. 动词 [使用码表具体映射的动作]

Decode(解码): 使用 ISO8859-1 编码解析文件 a 的二进制内容

基本概念

Transcoded(转码): 将文件 a 从 ISO8859-1 变为 UTF-8 编码.

字符 a 二进制从

[97] 转换为 [97] 码表中的映射值一样.

字符 ä 二进制从

[228] 转换为 [195, 164] 码表中的映射值一样.

问题

乱码的问题

* “ä” 使用了 UTF-8 编码(Encoding) 存储在文件 a, 拥有两个字节 [195, 164].

* 使用 ISO8859-1 编码(Encoding) 读取文件 a 中的 [195, 164] , 读取为 或者

Ruby 中的编码

Net

File System

Source Code

IO 入口

Ruby VM

TCP/IP(UDP) Socket

Unix Socket

* 通过 HTTP 协议过来的 Meta 信息

* 通过 MySQL 协议过来的编码信息

* 常规 IO 猜测

* Binary (ASCII-8bit)

Ruby 2.0 默认 UTF-8 编码

* IO 指定: open(‘./a’, ‘r:utf-8’)

* 尝试 Encoding.default_external

* Encoding.internal
Encoding.default_internal

自动将内部编码进行统一

Encoding.default_internal

问题

Incompatible character encodings: ASCII-8BIT and UTF-8

1. Ruby VM 内是多编码同时存在

2. 两个不同编码的字符串相加 (想想在 Rails 的 View 中)

3. 两个编码中不包含 ASCII 编码外的字符

“a”(utf-8) + “b”(iso8859-1) => “ab”(utf-8)

“a”(utf-8) + “ä”(iso8859-1) => Error

问题

Ruby 中 Unable to convert "\x89" from ASCII-8BIT to UTF8

这个我也还没完全弄懂...

猜测:

1. 子节流被 Ruby 标记为 ASCII-8BIT(Binary)

2. 使用 UTF-8 编码进行解码

3. 出现不符合 UTF-8 规则的二进制字节组合

参考

Ruby 与编码 - Google Slides