资源路径中包含汉字引发的字符串编码问题

2017/03/09

资源路径中包含汉字

一般来说 从系统api中取出来的地址都是进过UTF8编码的。如果自己通过借助文件系统找出部分地址,再通过获取可能包含汉字的文件名 来拼接出完整地址时,需要自己手动进行UTF8编码。 NSString *imagePath = [imagePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

ASCII编码 GB2312编码 Unicode编码 UTF8编码 UTF16编码 这些都是嘎哈滴呢?

ASCII编码:最开始计算机用1和0表达人们用的语言,就发明了ASCII码 用一个字节总共有255个不同状态表达可以表达255种字符 其实当时也就用上了一半就足以表达一些通用的简单的字符和英文字母。

GB2312编码:后来计算机流传了中国,汉字太多,后面的一半儿127位也不够哇,就将两个相邻的大于127的字符组合起来。来表示汉字。这种汉字方案叫做 “GB2312“。GB2312 是对 ASCII 的中文扩展。汉字两个字节,英文一个字节,混编。

Unicode编码:就这样,咱们中国自己有一套编码,其他国家也是,慢慢的,编码格式变得很多很多,不同地区的人要想电脑上现实其他的地区的文字,就必须安装文字系统。特别麻烦。所以这是有个统一的组织出现了, ISO (国际标谁化组织)发明了Unicode编码。统一用两个字节(16位)来表示。512个位置可以表达 65,536 个字符(2的16次方)。这会够多了吧,可以包含所有国家正在使用的文字和字符了。大家装这一套编码机制就行了。其中组织规定的抽象意义的码点,比如笑脸,在不用平台可能表示的字形或者图形不一样,U+1F61B 代表名为“伸出舌头的脸”的 emoji。 后来又扩展到了 21位,现在的NSString底层处理unicode就是21位,仅仅用到了10%的空间,还有相当大的剩余,

UTF8/UTF16编码:Unicode编码可以说 是用来表达语义的。但是不方便做互联网的传输,因为传输是可能出错的。需要额外的位置来做验证信息,比如奇偶校验位等等,UTF-8就是每次8个位传输数据,而UTF-16就是每次16个位。帮助Unicode 处理校验位。UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,UTF(UCS Transfer Format)是一种传输标准,为了解决Unicode编码的传输问题的。

计算机只懂二进制,因此,严格按照unicode的方式(UCS-2),应该这样存储:

I 00000000 01001001
t 00000000 01110100
' 00000000 00100111
s 00000000 01110011
  00000000 00100000
知 01110111 11100101
乎 01001110 01001110
日 01100101 11100101
报 01100010 10100101

这个字符串总共占用了18个字节,但是对比中英文的二进制码,可以发现,英文前9位都是0!浪费啊,浪费硬盘,浪费流量。

怎么办?

UTF。

UTF-8是这样做的:

  1. 单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;
  2. n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,这n个字节的其余空位填充该字符unicode码,高位用0补足。

这样就形成了如下的UTF-8标记位:

0xxxxxxx 110xxxxx 10xxxxxx 1110xxxx 10xxxxxx 10xxxxxx 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx … …

于是,”It’s 知乎日报“就变成了:

I 01001001
t 01110100
' 00100111
s 01110011
  00100000
知 11100111 10011111 10100101
乎 11100100 10111001 10001110
日 11100110 10010111 10100101
报 11100110 10001010 10100101

和上边的方案对比一下,英文短了,每个中文字符却多用了一个字节。但是整个字符串只用了17个字节,比上边的18个短了一点点。

Post Directory