Repository navigation
Expand file tree
/
Copy pathchar-encoding.html
More file actions
232 lines (209 loc) · 9.9 KB
/
Copy pathchar-encoding.html
File metadata and controls
232 lines (209 loc) · 9.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>字符编码</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="dirtysalt" />
<link rel="shortcut icon" href="./themes/favicon.ico" /><link rel="stylesheet" type="text/css" href="./themes/simple.css"/></head>
<body>
<div id="content">
<h1 class="title">字符编码</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orge6dcf4f">1. 切换编码考虑</a></li>
<li><a href="#orge6aa4aa">2. GB2312-80/GBK/GB18030</a></li>
<li><a href="#orga9331e7">3. Unicode</a></li>
<li><a href="#org3e57300">4. UTF16/UTF32</a></li>
<li><a href="#org75108c2">5. UTF8</a></li>
</ul>
</div>
</div>
<ul class="org-ul">
<li><a href="http://tech.idv2.com/2008/02/21/unicode-intro/">http://tech.idv2.com/2008/02/21/unicode-intro/</a></li>
<li><a href="http://www.unicode.org/charts/unihan.html">http://www.unicode.org/charts/unihan.html</a></li>
<li><a href="http://www.joelonsoftware.com/articles/Unicode.html">http://www.joelonsoftware.com/articles/Unicode.html</a></li>
</ul>
<div id="outline-container-orge6dcf4f" class="outline-2">
<h2 id="orge6dcf4f"><span class="section-number-2">1</span> 切换编码考虑</h2>
<div class="outline-text-2" id="text-1">
<ul class="org-ul">
<li>数据容量</li>
<li>网页压缩</li>
<li>字符串操作</li>
<li>编码转换性能</li>
<li>程序逻辑</li>
</ul>
</div>
</div>
<div id="outline-container-orge6aa4aa" class="outline-2">
<h2 id="orge6aa4aa"><span class="section-number-2">2</span> GB2312-80/GBK/GB18030</h2>
<div class="outline-text-2" id="text-2">
<p>
编码方式都是2字节,对于GB18030也有4字节表示.
</p>
<ul class="org-ul">
<li>GB2312-80是每个字节第一位均为1.c(0)在0xB0-0xF7之间,c(1)在0xA0-0xFE之间.</li>
<li>GBK完全兼容GB2321-80.所有字节均可一对一映射到Unicode2.0.c(0)在0x81-0xFE之间,c(1)在0x40-0xFE之间,剔除XX7F这条线.引入这个编码的原因是因为GB2310-80里面存在很多繁体字在开始的时候并没有经常使用但是之后却是用频繁.GBK的补充是引入了单字节欧元字符0x80.本来GB18030-2000里面的欧元字符0x80和0xA2E3,对应UCS-2里面U+20AC和U+E76C,但是结果GB18030-2005里面废除了0x80只是0xA2E3对应U+20AC.所以欧元里面存在的问题就是0x80 or 0XA2E3对应U+20AC以及是否识别0x80.</li>
<li>GB18030存在两个版本GB18030-2000和GB18030-2005.2000是在GBK基础上面增加了CJK统一扩充A汉字,2005是在2000基础上面增加了CJK统一扩充B汉字.所有字节均可一对一映射到Unicode.</li>
</ul>
<p>
下面是GB18030编码分布
</p>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<colgroup>
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-left" />
<col class="org-right" />
<col class="org-right" />
<col class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">类型</th>
<th scope="col" class="org-left">第一字节</th>
<th scope="col" class="org-left">第二字节</th>
<th scope="col" class="org-left">第三字节</th>
<th scope="col" class="org-left">第四字节</th>
<th scope="col" class="org-right">码位数</th>
<th scope="col" class="org-right">字符数</th>
<th scope="col" class="org-left">类型</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">双字节</td>
<td class="org-left">0xB0-0xF7</td>
<td class="org-left">0xA1-0xFE</td>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-right">6768</td>
<td class="org-right">6763</td>
<td class="org-left">汉字</td>
</tr>
<tr>
<td class="org-left">双字节</td>
<td class="org-left">0x81-0xA0</td>
<td class="org-left">0x40-0xFE</td>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-right">6080</td>
<td class="org-right">6080</td>
<td class="org-left">汉字</td>
</tr>
<tr>
<td class="org-left">双字节</td>
<td class="org-left">0xAA-0xFE</td>
<td class="org-left">0x40-0xA0</td>
<td class="org-left"> </td>
<td class="org-left"> </td>
<td class="org-right">8160</td>
<td class="org-right">8160</td>
<td class="org-left">汉字</td>
</tr>
<tr>
<td class="org-left">四字节</td>
<td class="org-left">0x81-0x82</td>
<td class="org-left">0x30-0x39</td>
<td class="org-left">0x81-0xFE</td>
<td class="org-left">0x30-0x39</td>
<td class="org-right">6530</td>
<td class="org-right">6530</td>
<td class="org-left">CJK统一扩充汉字A</td>
</tr>
<tr>
<td class="org-left">四字节</td>
<td class="org-left">0x95-0x98</td>
<td class="org-left">0x30-0x39</td>
<td class="org-left">0x81-0xFE</td>
<td class="org-left">0x30-0x39</td>
<td class="org-right">42711</td>
<td class="org-right">42711</td>
<td class="org-left">CJK统一扩充汉字B</td>
</tr>
</tbody>
</table>
<p>
这里面有必要提及一下全角和半角之间的差别.GBK希望对于ASCII字符统一按照两个字节来进行处理,所以对于那些ASCII字符的话有全角和半角之分.全角的ASCII使用2个字节,而半角的ASCII还是使用1个字节.
</p>
</div>
</div>
<div id="outline-container-orga9331e7" class="outline-2">
<h2 id="orga9331e7"><span class="section-number-2">3</span> Unicode</h2>
<div class="outline-text-2" id="text-3">
<p>
Unicode是为了整合全世界所有的语言文字而诞生的.任何文字在Unicode中都对应一个值,这个值称为码点(code point).文字和码点之间对应关系如果是2个字节表示一个文字的话,那么就是UCS(Unicode Character Set)-2关系,如果是4个字节的话那么就是UCS-4关系.表达是U+XXXX.,U+XXXXXXXX这样来写.但是UCS-2,UCS-4只是规定和对应的关系但是却没有规定如何存储.关于存储方面应用较多的就是UTF(Unicode Transformation Format)
</p>
<p>
下面是Unicode中的CJK范围
</p>
<pre class="example">
BEGIN Valid UniHan Ranges for this release (5.1.0):
U+3400..U+4DB5 : CJK Unified Ideographs Extension A
U+4E00..U+9FA5 : CJK Unified Ideographs
U+9FA6..U+9FBB : CJK Unified Ideographs (4.1)
U+9FBC..U+9FC3 : CJK Unified Ideographs (5.1)
U+F900..U+FA2D : CJK Compatibility Ideographs (a)
U+FA30..U+FA6A : CJK Compatibility Ideographs (b)
U+FA70..U+FAD9 : CJK Compatibility Ideographs (4.1)
U+20000..U+2A6D6 : CJK Unified Ideographs Extension B
U+2F800..U+2FA1D : CJK Compatibility Supplement
END Valid UniHan Ranges for this release (5.1)
Unicode中的全角数字0xFF10-0xFF19
Unicode中的全角大小字母0xFF21-0xFF3A
Unicode中的全角小写字母0xFF41-0xFF5A
Unicode中的全角中文标点0xFF01-0xFF0F,0xFF1A-0xFF20,0xFF5B-0xFF65,0xFE30-0xFE4F,0xFE10-0xFE1F,0x3000-0x303F
Unicode中的日文平假名片假名和假名扩展0x3040-0x309F,0x30A0-0x30FF,0x31F0-0x31FF,0xFF65-0xFF9F
Unicode中的韩文拼音和字符0xAC00-0xD7AF,0x1100-0x11FF,0x3130-0x318F,0xFFA0-0xFFDC
Unicode全角和半角转换 uch>=0xFF00 && uch<=0xFF5E => (uch & 0x007f)+0x20
</pre>
</div>
</div>
<div id="outline-container-org3e57300" class="outline-2">
<h2 id="org3e57300"><span class="section-number-2">4</span> UTF16/UTF32</h2>
<div class="outline-text-2" id="text-4">
<p>
UTF使用2个字节来表示一个码点.很明显UTF16对应UCS-2关系.但是UTF16是一种具体的编码所以需要考虑大小端问题[Little-Endian和Big-Endian的关系].所以UTF16实际上包含3种编码方式
</p>
<ul class="org-ul">
<li>UTF16BE[big endian]</li>
<li>UTF16LE[little endian]</li>
<li>UTF16 //这个通过BOM(byte order mark)来进行标记</li>
</ul>
<p>
因为UCS-2没有定义FFFE,所以FFFE和FEFF就能够来判断是大端还是小端.UTF32对应UCS-4关系,使用4个字节表示一个码点.和UTF16一样也分little endian和big endian,也包含BOM这种方式.UCS-2引入了欧元字符为0x20ac.GBK->UCS2的转换一定是始终成功的.相反UCS-2向GBK的转换可能存在不对应字符.UTF16在U+0000-U+FFFF之间使用单一的16位编码单元[基本多语言级别],而在+U10000-U+10FFFF之间使用一对16位编码单元.FFFD在UCS-2里面是没有使用的,所以可以来做NO_MAPPING.
</p>
</div>
</div>
<div id="outline-container-org75108c2" class="outline-2">
<h2 id="org75108c2"><span class="section-number-2">5</span> UTF8</h2>
<div class="outline-text-2" id="text-5">
<p>
UTF8和UTF16/UTF32是两种不同的编码方法.16/32属于定长编码而utf8属于变长编码.使用字节长度从1~4不等.同时UTF8不需要考虑大端和小端问题.对应方式如下:
</p>
<pre class="example">
UCS-2/(UCS-4)
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
</pre>
<ul class="org-ul">
<li>使用&0xC0=0x80可以来判断是否为HEADER字节…:)..这个特性很不错:).0xFE和0xFF在UTF8中从未使用.</li>
<li>根据第一个字节就能够知道长度.可以看到最多31个x所以最多编入2^31个UCS代码.UCS-2(4)和UTF8转换的关系就是把所有的位收集起来然后散布出去.utf8表示未知字符串0xEF0xBB0xBF[BOM].那么直接略过这3个字.</li>
</ul>
</div>
</div>
</div>
<script src="https://giscus.app/client.js" data-repo="dirtysalt/dirtysalt.github.io" data-repo-id="MDEwOlJlcG9zaXRvcnk3MjYxNjc3Mw==" data-category="Announcements" data-category-id="DIC_kwDOBFQLRc4CPQvg" data-mapping="pathname" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="bottom" data-theme="light" data-lang="zh-CN" data-loading="lazy" crossorigin="anonymous" async></script></body>
</html>