作者lihgong ( )
看板Soft_Job
标题[心得] UNICODE
时间Mon Nov 6 13:26:44 2023
写嵌入式软体,离人类世界遥远,我只知道英文字ASCII code是1byte
小时候用倚天中文,BIG5编码每个字2byte
UNICODE似乎是2byte,可以表示全世界的文字,蒙蒙懂懂
阅读Joel On Software的第四章
https://www.books.com.tw/products/0010467041
这篇文章也可以在这里看到
https://www.cnblogs.com/AlphaAI/articles/3960296.html
----
原来UNICODE有个Code Point的概念
制定(桥)出这张code point的前辈,真的是伟大的成就
人类终於有一个共同的表示法,纪录每个字
所以用BIG5编码的文件,可以读入以後,"DECODE"成上述的编码(我觉得是UCS2)
在wchar_t的domain (u16)做字串处理
最後储存的时候,再"ENCODE"成其他格式,例如UTF-8
之前用Python的UNICODE感觉encode/decode难以理解
现在总算搞懂UTF-8是什麽,整理一份note记下来
https://lihgong.blogspot.com/2023/11/utf-8-unicode-utf-32-big5.html
----
patch, thanks to ybite, 更新UTF16 surrogate pair的资讯
这东西的概念是这样
1. UNICODE 0xD800 ~ 0xDFFF大家讲好不放东西;所以出现这种字元必定有诈!
一般状态是 2byte代表一个字,这种状态变成4byte代表一个字
很多地方都有类似的招数
2. 要把UNICODE的U+10000 ~ U+10FFFF编进去,先把数值扣掉0x10000
看看他在16bit定址范围外的offset多少,这里的值域是0xFFFFF, 20bit
3. 编码规则如下
byte0 = offset[19:10] + 0xD800
byte1 = offset[9:0] + 0xDC00
4. 这种编码结构好处是self-synchronization,因为开头和结尾的值域固定下来了
如果中间有小错误也能侦测出来
缺点就LIB解析时,还有些额外的逻辑要弄,还真的有点麻烦;
不过比起用4byte字串的记忆体开销相比,应该勉勉强强能接受;
反正现在电脑效能过剩,小事啦!
----
後记3
感谢 *Dracarys 推荐的两篇文章,过了20Y,和Joel当初的文章互相辉映!
*
https://tonsky.me/blog/emoji/
*
https://tonsky.me/blog/unicode/
原来UNICODE有Extended grapheme cluster
A上面多带一个圈,可以是U+00C5或是U+0041 U+030A
我看过芬兰人的键盘,他们能打出某些特殊的上下标,亚洲人的我难以想像
所以A多带个圈(两个code point,符合我看他们键盘的感觉)
或是一个code point直接代表这个字,反应人类描述文字这件事,自带的复杂度
直观来看,所有文字都可以用UTF-32来表示?还是不行,有上述那些复杂的cases
所以作者说,处理UNICODE请用LIB,而且要按时更新的LIB(每年都会修订)
以我来说,就是体认UNICODE有自带的复杂度,不是像C的字串那麽简单的东西
这两篇文章确实看完就打通任督二脉,非常感谢
----
後纪4
关於UNICODE BOM (byte-order mark)
有个u16的数值,0xFE FF
这个数值用little-endian表示(大多数的电脑),在记忆体里会是0xFF 0xFE
如果用big-endian表示,会是0xFE 0xFF
一份文件用UTF-16储存,编辑器打开,不知道这份文件的endian
假如开头是0xFF 0xFE,那就是little-endian
假如开头是0xFE 0xFF,那就是big-endian
我觉得上面的例子很烂,因为FE/FF实在长得太相似
写AA/BB可能更容易看清楚,不过标准就长这样...
具体的资料可以看下面WIKI连结,有标准的BOM定义
https://reurl.cc/GKYxrW
另外更general的问题是,这两种endian的好与坏,可以参考下面文章
https://hackmd.io/@chenishi/BJRaOrGCX?type=view
网路传输里,先传送big-endian天生是比较顺的
比如有笔u32资料0xaabbccdd,传输协定规定从MSB to LSB做CRC
假如是little-endian的机器,那就得这样灌入CRC
注意阵列的顺序是倒置的...
data[3](0xaa) -> data[2](0xbb) -> data[1](0xcc) -> data[0](0xdd)
如果这台机器是big-endian,这样灌入CRC就很顺了
data[0](0xaa) -> data[1](0xbb) -> data[2](0xcc) -> data[3](0xdd)
操起for-loop,big-endian就是顺(直觉)很多
for(i=0; i<4; i++) {
calc_crc(data[i])
}
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 61.220.100.151 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Soft_Job/M.1699248406.A.A68.html
1F:推 wsad50232: 热心推 11/06 16:42
2F:推 now99: 推 11/06 23:40
3F:推 wuyiulin: 有料分享就推 11/06 23:41
4F:推 saladim: 推 当初直觉该encode怎麽叫作decode 傻了一阵子 ORZ 11/07 02:21
5F:推 geoege022702: 推推推 11/07 11:40
6F:推 ToastBen: 推 11/07 15:49
7F:→ ybite: Unicode 目前已经快破15万字 无法塞进2byte了 11/07 17:32
8F:→ ybite: 因此UTF-16定义Surrogate Pair来解决(一个字32bit) 11/07 17:41
9F:→ ybite: Python 2的时候str是ASCII 後来新增了unicode 型态 11/07 17:48
10F:→ ybite: Python 3 其中一个大改就是str 一定是一串Unicode文字 11/07 17:48
11F:→ ybite: (unicode扶正str)需要转成特定编码再.encode('utf-8') 11/07 17:49
12F:→ ybite: encode出来的是bytes 11/07 17:50
13F:→ ybite: 然後传统编码 如big5 就是要建一张大表对应Unicode 11/07 17:52
14F:→ ybite: 也由於各种历史原因 其实这个对应并没有很完全做到1:1 11/07 17:52
15F:→ ybite: 如PTT的Big5日文 後来很长时间是用由but维护的「社群标准」 11/07 17:55
16F:→ ybite: Unicode补完计画来当对应表 11/07 17:55
17F:→ ybite: 直到後来PTT内建UTF-8编码输出模式後才解决很多问题 11/07 17:56
18F:→ ybite: 每个语言或每个作业系统都有自己内部存Unicode的规格 11/07 17:57
19F:→ ybite: Python是PyUnicodeObject(PEP-393) 11/07 18:02
20F:→ ybite: 我还记得当年Python 2处理编码真的是地狱 11/07 18:03
21F:→ ybite: Unicode补完计画最早是直接patch Windows 的cp950对应表 11/07 18:09
22F:→ ybite: 後来UTF-8变成压倒性主流後 剩下PTT内部资料转换的情境了 11/07 18:09
23F:→ MoonCode: 楼上好猛 11/07 22:12
24F:→ superpandal: 喔 11/07 23:04
※ 编辑: lihgong (122.116.164.102 台湾), 11/07/2023 23:18:41
25F:→ lihgong: 感谢*ybite,我把Surrogate Pair资讯也补上 11/07 23:19
26F:推 Bencrie: 啊不过同一个汉字不同写法用同一个 code point 问题无解 11/07 23:41
27F:推 Bencrie: 然後难的地方在复杂语系一堆规则。 11/07 23:45
28F:→ labbat: 放弃UTF-16吧,投入可变字串长度UTF-8的世界 11/07 23:53
29F:推 zzLin: 好文,学习了 11/08 00:21
30F:推 eopXD: 推 11/08 05:13
31F:推 Dracarys: 再看完这两篇就打通任督二脉了 11/08 09:13
34F:推 jheli: 优质文,推推 11/08 09:28
35F:推 Mtcat: 1 11/08 14:40
36F:推 yuinami: 感谢分享 11/08 22:33
37F:推 askacis: 你应该是写MCU之类的吧,Embedded Linux也是会碰Unicode 11/09 11:21
38F:→ lihgong: 感谢 *Dracarys 我把您推荐的文章也补在後记上,非常赞 11/10 23:48
※ 编辑: lihgong (122.116.164.102 台湾), 11/10/2023 23:59:30
39F:推 kikilalagirl: 看能不能再补充 BOM 的资讯? 系统常遇到这类问题. 11/11 00:29
※ 编辑: lihgong (122.116.164.102 台湾), 11/11/2023 09:51:55
40F:→ lihgong: 感谢 *kikilalagirl 我也顺便搞清楚BOM和endian的优缺 11/11 09:53
41F:推 art1: 之前碰的传输协定是小端传输,CRC 也是从小端开始 11/12 06:55
42F:推 yiche: 推推 最近接触到bom utf-8 上网看了一下是什麽格式 就看到 11/12 09:26
43F:→ yiche: 原po撰文了 11/12 09:26
44F:推 kentyeh: 大推Dracarys的两篇文章,不过阅读顺序应该反过来 11/12 22:57
45F:推 shibin: 推 11/19 12:36
46F:推 Falldog: 推 12/07 08:48