阮一峰的文章有哪些常见性错误

2017-02-27 20:48:40 +08:00
 lzjun

比如《字符编码笔记: ASCII , Unicode 和 UTF-8 》 是阮老师 10 年前写的一篇关于字符编码的科普文章,现在用 Google 搜关键字该文章依然名列前茅,可见他的文章有多大影响力,但里面的内容是否正确是值得商榷的事。

中文维基百科对 Unicode 的解释也是让人一头雾水,摸不着头脑。看看阮老师怎么说:

可以想象,如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode ,就像它的名字都表示的,这是一种所有符号的编码。

这句话读起来很拗口,有三个地方出现了「编码」二字。不知阮老师对「编码」的理解是什么?但可以肯定的是这三个「编码」在这句话里面不是同一个意思。

「编码」作动词使用时就是把一个字符(严格一点说是字符在字符集中的编号 code point )转换成一个字节序列,以便在网络传输或者存储到文本中。比如「好」在 Unicode 中的编号是 U+597d ,经过 UTF-8 编码后会转换成二进制序列是 '\xe5\xa5\xbd' 。作为名词使用时,就是指一种具体的编码实现方式,比如 ASCII 编码, GBK 编码, UTF-8 编码

其实 Unicode 是一个囊括了世界上所有字符的字符集,其中每一个字符都对应有唯一的编码值( code point ),然而它并不是一种什么编码格式,仅仅是字符集而已。 Unicode 字符要存储要传输怎么办,它不管,可以用 UTF-8 、 UTF-16 。

再来看阮老师说 Unicode 的第二个问题:

第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是 0 ,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。

Unicode 并没有统一规定每个符号用三个或者四个字节表示。 Unicode 只规定了每个字符对应到唯一的代码值( code point ),代码值 从 0000 ~ 10FFFF 共 1114112 个值 ,真正存储的时候需要多少个字节是由具体的编码格式决定的。比如:字符 「 A 」用 UTF-8 的格式编码来存储就只占用 1 个字节,用 UTF-16 就占用 2 个字节,而用 UTF-32 存储就占用 4 个字节。

再看来看这张图:

阮老师对 Unicode 编码的解释是:

Unicode 编码指的是 UCS-2 编码方式,即直接用两个字节存入字符的 Unicode 码。这个选项用的 little endian 格式。

UCS-2 是什么鬼, UCS-2 是使用两个定长的字节来表示一个字符,而 UTF-16 是使用两个变长的字节,遇到两个字节没法表示时,会用 4 个字节来表示,因此 UTF-16 可以看作是在 UCS-2 的基础上扩展而来的。而 UTF-32 与 USC-4 是完全等价的。

之所以在 Windows 下有 Unicode 编码这样一种说法,其实是 Windows 的一种错误表示方法,它真正的编码类型是 UTF-16LE 编码。

他又说:

Unicode 规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"( ZERO WIDTH NO-BREAK SPACE ),用 FEFF 表示。这正好是两个字节,而且 FF 比 FE 大 1 。

如果一个文本文件的头两个字节是 FE FF ,就表示该文件采用大头方式;如果头两个字节是 FF FE ,就表示该文件采用小头方式

这儿就错得更加离谱了,不想说了,直接原文链接 http://mp.weixin.qq.com/s?__biz=MjM5MzgyODQxMQ==&mid=2650366798&idx=1&sn=5db3b152c99ff96f7a477313cfb175e0&chksm=be9cd81a89eb510c1d22091d89df648ab689a01fd77ebd4361567dd7ec238e754c3d5f10715c&mpshare=1&scene=23&srcid=0227ViQqcIpvWmVwkOiYxyxT#rd

18254 次点击
所在节点    程序员
115 条回复
chmlai
2017-02-28 11:04:58 +08:00
在中文网路, 阮一峰挺难得的
shyrock
2017-02-28 11:05:57 +08:00
第二个问题阮一峰说的是“如果”啊,你没看清就瞎喷。。。
skywalker
2017-02-28 11:07:13 +08:00
阮一峰最令人佩服的是能用简明扼要的语言去解释问题,这在国内技术圈是难能可贵的。有没有错误?当然会有了,但是又有什么关系。想了解任何技术,靠一篇文章、一本书都是不够的,你想了解 Unicode ,把这个作为一个起点,在读其它文档时对概念有所了解,不就很好吗? 伍尔夫说,我们在读书时,第一遍要做作者的朋友,第二遍要做审判官。有错误没有关系,只要有价值就行。

看到回复里那些阴阳怪气的,徒增笑耳。
liyu4
2017-02-28 11:07:15 +08:00
@kuntang 是的
comcuter
2017-02-28 11:07:53 +08:00
为什么要起这么大的一个标题, 我还以为是要把所有文章的常见错误都给挑出来呢
FrankHB
2017-02-28 11:09:36 +08:00
@vultr 首先找错误未必“花大量的时间”,内行可能一眼就注意了;而花时间告诉别人这里存在问题和“写几篇正确”作用类似,成本不同。同时没法要求有技术专长的人人都能高产赛母猪……
@DeutschXP 我有些好奇你如何揣测出“新人”“向上爬”。我在这里完全看不出这一点。
@ersic 太多人没注意到“个人笔记”的性质了。
@linxu 谓词(虽然也叫 predicate )看来不是你要说的意思……
@21grams 我觉得让人找不清楚门在哪里往哪边开是很不够意思的。
@stranbird 我经验的和你认为的正相反,大部分真·小白对这类内容来源是抱着跪舔的心思拜读的(其中的多数还不会说出来这种不长脸的事)。
DinoStray
2017-02-28 11:14:40 +08:00
@jsq2627
非常棒的推荐.
之前一直以为 java 是用 Unicode 保存字符, 那么实际到底用的哪种 UTF 格式?
clino
2017-02-28 11:17:58 +08:00
@fulvaz #66 你说的是这篇吗? http://www.ruanyifeng.com/blog/2006/12/how_to_get_an_idea.html
好奇你对这篇有什么评论?
zhidian
2017-02-28 11:22:42 +08:00
>>>
再来看阮老师说 Unicode 的第二个问题:

[ 第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是 0 ,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。]

Unicode 并没有统一规定每个符号用三个或者四个字节表示。 Unicode 只规定了每个字符对应到唯一的代码值( code point ),代码值 从 0000 ~ 10FFFF 共 1114112 个值 ,真正存储的时候需要多少个字节是由具体的编码格式决定的。比如:字符 「 A 」用 UTF-8 的格式编码来存储就只占用 1 个字节,用 UTF-16 就占用 2 个字节,而用 UTF-32 存储就占用 4 个字节。

---

阮老师说的是 [要是] unicode 这么设计的话,是多么浪费啊!你却认为阮老师说错了。所以你在逗我???你的槽点简直比他多一万倍好不好。
FrankHB
2017-02-28 11:25:52 +08:00
既然务求严谨,顺便纠正 LZ 的几个表述不清晰的地方(包括错误):
“其实 Unicode 是一个囊括了世界上所有字符的字符集,其中每一个字符都对应有唯一的编码值( code point ),然而它并不是一种什么编码格式,仅仅是字符集而已。 ”
—— Unicode 的本义大概是如此,不过现在早就跑飞了。现在的 Unicode 很难单独抠出“字符”的概念和日常的字符讲清楚(这是我认为 Unicode 辣鸡的地方,且按下不表)。例如, emoji 姑且可以认为是“字符”,但带颜色和不带颜色的 emoji 指派不同的 code point 是什么鬼?
“ UCS-2 是使用两个定长的字节来表示一个字符”
——编码 UCS-2 的是两个八元组(octet),不能和字节(byte)任意互换。
“而 UTF-16 是使用两个变长的字节”
——读起来难以言喻……
“之所以在 Windows 下有 Unicode 编码这样一种说法,其实是 Windows 的一种错误表示方法,它真正的编码类型是 UTF-16LE 编码。”
——因为历史原因,当年所谓的 Unicode 编码=UCS-2 ,因此也不全然是错误。反倒直接说 UTF-16 是有问题的。事实上, UTF-16 的普遍支持是 Windows 2000 加上去的(部分超出 BMP 字符的用户层机制如 WM_UNICHAR 在 Windows 7 之后才全面支持)。
“ Unicode 只规定了每个字符对应到唯一的代码值( code point ),代码值 从 0000 ~ 10FFFF 共 1114112 个值 ”
——历史上除了最开始的 16 位编码空间外,之后曾扩展到 32 位。限制 U+10FFFF 是 RFC 3629 时候的事。(顺便注意一下 UTF-8 的版本。)
sokis
2017-02-28 11:26:33 +08:00
跟阮一峰接触过,也听过他的培训,确实是个很有趣的人。。手动滑稽 :)
FrankHB
2017-02-28 11:30:30 +08:00
@zhidian 不巧,历史上 Unicode 和 ISO 10646 钦定的一些重要的方案如一开始的 16 位直接索引的编码和之后的 UTF-32/UCS-4 就是这样“浪费”的;退一步说,至少 UTF-8 发明之前就是这种状况。你的槽点又有几何呢……
grzhan
2017-02-28 11:36:22 +08:00
本来看标题以为是个关于阮老师的勘误集中贴

自己以前也看了不少阮老师的文章所以点进来想看看到底是有哪些错误……
FrankHB
2017-02-28 11:39:18 +08:00
@DinoStray Java 语言一开始使用 UCS-2 , J2SE 5 开始使用 UTF-16 ,现在由 JLS 规范。 Java 的一些 API 支持 UTF-8 和 MUTF-8(modefied UTF-8)。 JVMS 规定 JVM 的实现需要用到 MUTF-8 表示特定的字符串。一些其它实现如 Dalvik dex 也使用 MUTF-8 。
onlyhot
2017-02-28 11:43:18 +08:00
真是中文圈特色了吧,就没几个人讨论内容 呵呵
wyx
2017-02-28 12:17:43 +08:00
科普文有什么好挑错的...
Aspx
2017-02-28 13:01:39 +08:00
阮一峰真正牛逼的是人家能坚持写博客这么多年。另外是人就会犯错,又不是谁没犯过错。
jadecoder
2017-02-28 13:29:13 +08:00
「如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是 0 ,这对于存储来说是极大的浪费」

这么简单的一句话都读不懂,我觉得是楼主的问题
xuelu520
2017-02-28 14:03:52 +08:00
发表时间:日期: 2007 年 10 月 28 日。
楼主能看出这么多错误,说明也是认真去看了,这篇文章的目的就达到了。
有错就改就是了。
anoyafk
2017-02-28 14:25:05 +08:00
讨论内容就去阮一峰的博客评论

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/343634

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX