tag:blogger.com,1999:blog-67355753893882249672023-11-15T22:04:54.194-08:00点·心Carlhttp://www.blogger.com/profile/09568570315894174360noreply@blogger.comBlogger3125tag:blogger.com,1999:blog-6735575389388224967.post-18982200511651427872017-07-30T09:21:00.001-07:002017-07-30T09:21:20.728-07:00从乌镇学打造产品如今的乌镇不仅仅是一个旅游景点,除了古镇特色还有互联网大会,戏剧节等,在众多江南小镇中独具特色,今天听到他的创造者分享的经验,很有意思,用时间打磨出了一个很好的产品。<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFvkSQ8oTcVoUDN0pg6R_ETlLp1uhIZUOBDPvNK5UtpjuNXTTgLGO8JQ1SI0P0NSRCxZWlgwkZ6xmpjYYAYEw_XhDKhrMi3tAoQxLu7-aLq8CpXLoksexHYwBN64m9qe1ljRFV3Co_3fE/s1600/%25E4%25B9%258C%25E9%2595%2587%25E6%2588%2590%25E9%2595%25BF%25E5%258F%25B2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="577" data-original-width="1011" height="364" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFvkSQ8oTcVoUDN0pg6R_ETlLp1uhIZUOBDPvNK5UtpjuNXTTgLGO8JQ1SI0P0NSRCxZWlgwkZ6xmpjYYAYEw_XhDKhrMi3tAoQxLu7-aLq8CpXLoksexHYwBN64m9qe1ljRFV3Co_3fE/s640/%25E4%25B9%258C%25E9%2595%2587%25E6%2588%2590%25E9%2595%25BF%25E5%258F%25B2.jpg" width="640" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFvkSQ8oTcVoUDN0pg6R_ETlLp1uhIZUOBDPvNK5UtpjuNXTTgLGO8JQ1SI0P0NSRCxZWlgwkZ6xmpjYYAYEw_XhDKhrMi3tAoQxLu7-aLq8CpXLoksexHYwBN64m9qe1ljRFV3Co_3fE/s1600/%25E4%25B9%258C%25E9%2595%2587%25E6%2588%2590%25E9%2595%25BF%25E5%258F%25B2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFvkSQ8oTcVoUDN0pg6R_ETlLp1uhIZUOBDPvNK5UtpjuNXTTgLGO8JQ1SI0P0NSRCxZWlgwkZ6xmpjYYAYEw_XhDKhrMi3tAoQxLu7-aLq8CpXLoksexHYwBN64m9qe1ljRFV3Co_3fE/s1600/%25E4%25B9%258C%25E9%2595%2587%25E6%2588%2590%25E9%2595%25BF%25E5%258F%25B2.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
这种经过规划+长时间精细打磨+不停注入特色 的产品,值得反复去体会和揣摩,那么问题来了,啥时候去乌镇放松心灵呢~~~Carlhttp://www.blogger.com/profile/09568570315894174360noreply@blogger.com0tag:blogger.com,1999:blog-6735575389388224967.post-51305901162001332212017-05-07T10:57:00.000-07:002018-03-12T08:28:45.614-07:00字符编码/字符集详解<h2>
一.引言</h2>
<div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'PingFang SC'; color: #454545}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #454545; min-height: 14.0px}
span.s1 {font: 12.0px Helvetica}
</style>
<br />
<div class="p1">
工作中,经常会遇到乱码,字符集转换等问题,尤其在<span class="s1">python</span>处理汉字,以及<span class="s1">MySQL</span>生僻字处理的时候。本文详细解释下字符集以及字符编码的用途,关于<span class="s1">python</span>处理中文,以及<span class="s1">MySQL</span>中的字符集相关,后续再聊。</div>
<div class="p2">
<br /></div>
<div class="p1">
我们知道,计算机看到的都是二进制,文本文件中的<span class="s1">0/1</span>,怎么转换成人类可读的文字呢?这就涉及到编码以及解码,简单来说将<span class="s1">0/1</span>进行结构化解读,通过字符集-编码-解码的对应关系,进行正确地存储和读取。</div>
<div class="p1">
那问题来了,编解码到底是怎么个过程,字符集是什么?有哪些字符集,它们之间哪些兼容哪些不兼容?下文尝试解释清楚。</div>
<div class="p1">
</div>
<a name='more'></a><br />
<h2>
二.名词解释</h2>
<br />
<ul>
<li>bit</li>
<ul>
<li>一个二进制位,可以取值<span class="s1">0</span>或者<span class="s1">1</span>。两个<span class="s1">bit</span>可以组成二进制的<span class="s1">00,01,10,11. N</span>个<span class="s1">bit</span>可以表达<span class="s1">2</span>的<span class="s1">N</span>次方个可能的值。</li>
</ul>
<li>字节</li>
<ul>
<li>一个字节包含8 bit,所以二进制表达范围可以从00000000~11111111。一共可以表达256种不同的值。字节是计算机存储的基本单位。</li>
</ul>
<li>字符</li>
<ul>
<li>指计算机中可以使用的独立的数字,符号,各国家文字,emoji表情等等。每个英文字母就是一个单字节字符。而一个中文的字符,可能占2个或三个甚至4个字节,所占字节数的不同是因为字符编码不同导致。每个字符都需要有对应的编解码规则才能被计算机处理。在对字符进行编码时,每个字符对应的编码位置称为码位(code point)。</li>
</ul>
<li>字符集</li>
<ul>
<li>是多个字符的集合,表达了字符与字符同一个字符集内的字符采用同一套编解码规则,而由于其采用的编解码规则的不同,导致每个字符集所能表示的字符的数量也有不同,每个字符集表达的能力是有范围限制的。 常见字符集包括ASCII, GBK, GB2312, UTF-8等。</li>
</ul>
<li>大端/小端(big endian/little endian)</li>
<ul>
<li>关乎计算机如何处理内存中的多个字节。只针对多字节字符时需要考虑(UTF-8下不需要考虑,原因见下文)。例如“汉”字的unicode编码是6C49,写入文件时到底是6C还是49写在前面决定了读取编码的正确姿势。6C在前就是big endian , 49在前就是little endian。</li>
<li>大小端的存在是因为各组织的设备处理字符时采用了不同的方式。例如IBM服务器默认使用小端方式,而<span style="background-color: white;">Motorola/</span>SUN等使用大端方式。当不同设备之间进行文件传输或者网络传输时,需要让对方明确知道自己的字节顺序,否则必然出错。</li>
<li>八卦一下这种叫法的出处:《<span style="font-family: "microsoft yahei"; font-size: 13px; white-space: nowrap;">格列佛游记</span>》中人们常常争论"吃鸡蛋时先敲碎鸡蛋的大端还是小端",这些争论甚至会引发战争~</li>
</ul>
</ul>
<br />
<h2>
三.常见字符集及其字符编码</h2>
<h3>
1.ASCII字符集</h3>
<div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'PingFang SC'; color: #454545}
span.s1 {font: 12.0px Helvetica}
</style>
<br />
<div class="p1">
<span style="font-family: "helvetica";"> ASCII(American Standard Code for Information Interchange 美国信息交换标准代码)码使用一个字节中的7位来表示一个字符,所以这个字符集能表达128个字符,其编码方式ASCII码表如下:</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQq3Xw7e-QLcwk0t-ff3hyhmZeO8RLRU6JCFa5ARqZXQuKStnxjluhauLiJrOMvcrOk1rzalZU8eTPN6jdx2Xs_qOWptWoUSNnZfiAiyhgnnguSCdgOZNB3U4UnYRQKD8ZdrhOYPzQ5W0/s1600/ascii.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQq3Xw7e-QLcwk0t-ff3hyhmZeO8RLRU6JCFa5ARqZXQuKStnxjluhauLiJrOMvcrOk1rzalZU8eTPN6jdx2Xs_qOWptWoUSNnZfiAiyhgnnguSCdgOZNB3U4UnYRQKD8ZdrhOYPzQ5W0/s320/ascii.png" width="320" /></a></div>
<span style="font-family: "helvetica";"><br /></span>
<span style="font-family: "helvetica";">该字符集最古老也最受限,基本只能满足早期英语国家的基本需求。</span><br />
<span style="font-family: "helvetica";"> 我们注意到一个字节是8位,而ASCII只定义了其中7位的含义,最高位加入后能够表达的</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">128-255号的字符被不同国家地区进行了不同的字符映射,比如</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">,144在阿拉伯人的ASCII码中是</span><span style="background-color: white; box-sizing: border-box; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px; font-weight: 700;">گ</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">,而在俄罗斯的ASCII码中是</span><span style="background-color: white; box-sizing: border-box; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px; font-weight: 700;">ђ。</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">这给解码造成了大麻烦。这个麻烦的解决引入了</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">内码表(即编码的翻译表)进行解决,悲催的是,使用者需要清楚不同时候切换正确的内码表。</span><br />
<h3>
<span style="font-family: "helvetica";">2.GB2312, BIG5, GBK, GB18030字符集</span></h3>
<div class="p1">
ASCII字符集处理不了中文,为了处理汉字,我国开始发布简体中文汉字国家标准。现有出现了GB2312, GBK, GB18030编码。而以前见到过的BIG5是台湾地区单独发布的繁体字字符集。</div>
<div class="p1">
</div>
<ul>
<li>GB2312</li>
<ul>
<li>1981年5月1日发布的简体中文汉字编码国家标准。GB2312对汉字采用双字节编码,收录7445个图形字符,其中包括6763个汉字。</li>
</ul>
<li>BIG5</li>
<ul>
<li>台湾地区繁体中文标准字符集,采用双字节编码,共收录13053个中文字,1984年实施。</li>
</ul>
<li>GBK</li>
<ul>
<li>1995年12月发布的汉字编码国家标准,是对GB2312编码的扩充,对汉字采用双字节编码。GBK字符集共收录21003个汉字,包含国家标准GB13000-1中的全部中日韩汉字,和BIG5编码中的所有汉字。</li>
</ul>
<li>GB18030</li>
<ul>
<li>2000年3月17日发布的汉字编码国家标准,是对GBK编码的扩充,覆盖中文、日文、朝鲜语和中国少数民族文字,其中收录27484个汉字。GB18030字符集采用单字节、双字节和四字节三种方式对字符编码。兼容GBK和GB2312字符集。</li>
</ul>
</ul>
可以看到,字符集表达范围为 GB2312 < GBK < GB18030,他们之间互相兼容,但是BIG5与他们三个完全不兼容。</div>
</div>
<div>
<h3>
3.Unicode字符集以及UTF-8/UTF-16字符编码</h3>
<div class="p1">
GB码是中国国家发布的字符编码,而非国际标准。Unicode,通用字符集(<span class="s1">Universal Multiple-Octet Coded Character Set</span>,<span class="s1">UCS</span>),是国际标准字符集,它将世界各种语言的每个字符定义一个唯一的数字表达,以满足跨语言、跨平台的文本信息转换。Unicode字符集与ASCII编码兼容,但是和GB码并不兼容。<br />
看一下下面的字符编码表达示例,直观感受下,包括普通英文字母,汉字以及emoji表情:<br />
<br />
<style>
<!--table
{mso-displayed-decimal-separator:"\.";
mso-displayed-thousand-separator:"\,";}
@page
{margin:1.0in .75in 1.0in .75in;
mso-header-margin:.5in;
mso-footer-margin:.5in;}
.font5
{color:windowtext;
font-size:9.0pt;
font-weight:400;
font-style:normal;
text-decoration:none;
font-family:宋体, sans-serif;
mso-font-charset:134;}
td
{padding-top:1px;
padding-right:1px;
padding-left:1px;
mso-ignore:padding;
color:black;
font-size:12.0pt;
font-weight:400;
font-style:normal;
text-decoration:none;
font-family:宋体, sans-serif;
mso-font-charset:134;
mso-number-format:General;
text-align:general;
vertical-align:bottom;
border:none;
mso-background-source:auto;
mso-pattern:auto;
mso-protection:locked visible;
white-space:nowrap;
mso-rotate:0;}
.xl63
{font-weight:700;
border:.5pt solid windowtext;}
.xl64
{text-align:left;
vertical-align:top;
border:.5pt solid windowtext;}
.xl65
{color:#111111;
font-size:15.45pt;
font-family:"PingFang SC", monospace;
mso-font-charset:134;
text-align:left;
vertical-align:top;
border:.5pt solid windowtext;}
.xl66
{color:#111111;
font-size:15.45pt;
font-family:仿宋;
mso-generic-font-family:auto;
mso-font-charset:0;
text-align:left;
vertical-align:top;
border:.5pt solid windowtext;}
ruby
{ruby-align:left;}
rt
{color:windowtext;
font-size:9.0pt;
font-weight:400;
font-style:normal;
text-decoration:none;
font-family:宋体, sans-serif;
mso-font-charset:134;
mso-char-type:none;
display:none;}
-->
</style>
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 390px;">
<!--StartFragment-->
<colgroup><col span="6" style="width: 65pt;" width="65"></col>
</colgroup><tbody>
<tr height="15" style="height: 15.0pt;">
<td class="xl63" height="15" style="height: 15.0pt; width: 65pt;" width="65">字符</td>
<td class="xl63" style="border-left: none; width: 65pt;" width="65">GB2312</td>
<td class="xl63" style="border-left: none; width: 65pt;" width="65">GBK</td>
<td class="xl63" style="border-left: none; width: 65pt;" width="65">GB18030</td>
<td class="xl63" style="border-left: none; width: 65pt;" width="65">BIG5</td>
<td class="xl63" style="border-left: none; width: 65pt;" width="65">UNICODE</td>
</tr>
<tr height="22" style="height: 22.0pt;">
<td class="xl64" height="22" style="border-top: none; height: 22.0pt;">X</td>
<td class="xl65" style="border-left: none; border-top: none;">58</td>
<td class="xl65" style="border-left: none; border-top: none;">58</td>
<td class="xl65" style="border-left: none; border-top: none;">58</td>
<td class="xl65" style="border-left: none; border-top: none;">58</td>
<td class="xl65" style="border-left: none; border-top: none;">58</td>
</tr>
<tr height="22" style="height: 22.0pt;">
<td class="xl64" height="22" style="border-top: none; height: 22.0pt;">汉</td>
<td class="xl65" style="border-left: none; border-top: none;">BABA</td>
<td class="xl65" style="border-left: none; border-top: none;">BABA</td>
<td class="xl65" style="border-left: none; border-top: none;">BABA</td>
<td class="xl66" style="border-left: none; border-top: none;">无</td>
<td class="xl65" style="border-left: none; border-top: none;">6C49</td>
</tr>
<tr height="22" style="height: 22.0pt;">
<td class="xl64" height="22" style="border-top: none; height: 22.0pt;">囍</td>
<td class="xl64" style="border-left: none; border-top: none;">无</td>
<td class="xl65" style="border-left: none; border-top: none;">87D6</td>
<td class="xl65" style="border-left: none; border-top: none;">87D6</td>
<td class="xl65" style="border-left: none; border-top: none;">F8A6</td>
<td class="xl65" style="border-left: none; border-top: none;">56CD</td>
</tr>
<tr height="22" style="height: 22.0pt;">
<td class="xl64" height="22" style="border-top: none; height: 22.0pt;">䶮</td>
<td class="xl64" style="border-left: none; border-top: none;">无</td>
<td class="xl64" style="border-left: none; border-top: none;">无</td>
<td class="xl65" style="border-left: none; border-top: none;">FE9F</td>
<td class="xl64" style="border-left: none; border-top: none;">无</td>
<td class="xl65" style="border-left: none; border-top: none;">4DAE</td>
</tr>
<tr height="22" style="height: 22.0pt;">
<td class="xl64" height="22" style="border-top: none; height: 22.0pt;">😊</td>
<td class="xl64" style="border-left: none; border-top: none;">无</td>
<td class="xl64" style="border-left: none; border-top: none;">无</td>
<td class="xl65" style="border-left: none; border-top: none;">9439FD36</td>
<td class="xl64" style="border-left: none; border-top: none;">无</td>
<td class="xl65" style="border-left: none; border-top: none;">1F60A</td>
</tr>
<!--EndFragment-->
</tbody></table>
</div>
<div class="p1">
<br />
Unicode的一个显著特征,是强制定义了世界上每个已知字符的数字编码值,这个值甚至<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">可能是随机指定的,而且不会给出任何解释。具体的规则<a href="https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#.E5.9F.BA.E6.9C.AC.E5.A4.9A.E6.96.87.E7.A7.8D.E5.B9.B3.E9.9D.A2" target="_blank">Unicode字符平面映射</a>。</span><br />
<blockquote class="tr_bq">
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">再次强调!Unicode本身只是一个用来映射字符和数字的标准。它对支持字符的数量没有限制,也不要求字符必须占两个、三个或者其它任意数量的字节。</span></blockquote>
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">细细探索下</span><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">Unicode 的编码,目前分为17组编排,0x0000-0x10FFFF,每组称为一个平面,可以表示 65536 个字符。第一个平面中的字符是常用字符,称为 </span><em style="box-sizing: border-box; color: #333333; font-family: "Helvetica Neue", Helvetica, Arial, "Hiragino Sans GB", "Microsoft Yahei", sans-serif; font-size: 16px;">基本多语言平面(Basic Multilingual Plane, BMP)</em><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">,其他平面称为辅助平面。目前只用了少数平面。</span><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;">wikipedia中的图表引用至此。</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmPEaRSVvplvxJdthP5Zdn6ZUUhky5Xb_9jtnJM9GIIcpKNlwhHw5ZGs9VasRsIxXaiy8D4PeujEmIriPA5aHcL9fYzmw5XTNHdvc9Og_rSRk8JvvCGJQMaOc1ImGWMvWrTC2DEnwxtI0/s1600/bmp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="123" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmPEaRSVvplvxJdthP5Zdn6ZUUhky5Xb_9jtnJM9GIIcpKNlwhHw5ZGs9VasRsIxXaiy8D4PeujEmIriPA5aHcL9fYzmw5XTNHdvc9Og_rSRk8JvvCGJQMaOc1ImGWMvWrTC2DEnwxtI0/s320/bmp.png" width="320" /></a></div>
<span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;"><br /></span>
<span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;"><br /></span>
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">那么问题来了,</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">Unicode字符是怎样被编码成内存中的字节呢?目前常见的Unicode字符编码包括UTF-8以及UTF-16。我们分别看下这两种字符编码如何能够表达上述平面的信息。</span><br />
<h4>
3.1. UTF-8(Unicode Transformation Format-8 bits)</h4>
UTF-8将<span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">0x0000-0x10FFFF的编码空间</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">划分编号为1,2,3,4 的四段,这四段中的字符占用的空间分别是 1 个字节,2 个字节,3 个字节,4 个字节。如下图所示:</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh4YPDVLfGtleo4WkLV4nieJzicurWDZHzR_8uuE9Njb4VvA3f2Bg1cRKOWuqv_U9T7C4__imOxho3T3emBhm7v59Jl6vNZDc_AtTQoFkCEYo3d4Ww6TtyZHrmvK41Mv7dHJOzh7w_CVU/s1600/utf8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="70" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh4YPDVLfGtleo4WkLV4nieJzicurWDZHzR_8uuE9Njb4VvA3f2Bg1cRKOWuqv_U9T7C4__imOxho3T3emBhm7v59Jl6vNZDc_AtTQoFkCEYo3d4Ww6TtyZHrmvK41Mv7dHJOzh7w_CVU/s400/utf8.png" width="400" /></a></div>
<ul>
<li><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;">0x00-0x7F 单字节编码,即兼容ASCII。编码格式:0XXXXXXX</span></li>
<li></li>
<li><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;">0x080-0x7FF 两个字节编码。编码格式: 110XXXXX 10XXXXX</span></li>
<li><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;">0x0800-0xFFFF 三个字节编码。编码格式: 1110XXXX 10XXXXXX 10XXXXXX</span></li>
<li><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;">0x010000-0x10FFFF 四个字节编码,编码格式: 11110XXX </span>10XXXXXX 10XXXXXX 10XXXXXX</li>
</ul>
可以看到UTF-8对ASCII编码完全兼容!<br />
<br />
<blockquote class="tr_bq">
为什么UTF-8字符编码没有大小端之分?<br />
这里隐含着另外一个疑惑,既然每个字符可能是1-4个字节,为什么UTF-8全名里面包含了8 bits,这到底是什么鬼?<br />
本质上,UTF-8的编码方式是采用8bit即一个字节作为编码单位,解码算法的做法一次还是读取一个8bit(即一个字节)。读完一个读下一个,直接到计算出一个完整字符的信息。<br />
而UTF-16或者UTF-32,则使用16bit或者32bit作为编码单位,解码算法要处理UTF-16,则一次读取两个字节,这两个字节CPU处理的时候,就需要区分字节顺序了!<br />
既然UTF-8是基于字节进行编码,而大小端是针对多字节的字节顺序处理,那大小端在UTF-8下肯定就没有意义了!</blockquote>
<h4>
3.2. UTF-16</h4>
<span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">UTF-16相对UTF-8更复杂一点,具体编码方式可以查阅</span><span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;"><a href="https://zh.wikipedia.org/wiki/UTF-16" target="_blank">wikipedia</a>,不做展开。</span><br />
<span style="color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif;">UTF-16字符编码同样也是</span><span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">一种变长编码方案,使用2个字节或者4个字节来表示一个字符。对于常用字符使用2个字节表示(65536个字符),其他采用4个字节。</span><br />
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;"><br /></span>
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;">可以简单比较下</span>UTF-8和UTF-16,前者对ascii完全兼容,单字节就够。英语世界网络世界使用utf-8,基本没有迁移成本,而且相比utf-16节省了一半的字节消耗,优势明显。utf-8也是目前最普及的Unicode字符编码方式!<br />
<span style="background-color: white; color: #333333; font-family: "helvetica neue" , "helvetica" , "arial" , "hiragino sans gb" , "microsoft yahei" , sans-serif; font-size: 16px;"><br /></span>
<br />
<h4>
3.3. 关于BOM(Byte Order Mark)</h4>
<br />
BOM是一个Unicode字符,U+FEFF,可以用在一个文本流的开头,来标记<br />
<br />
<ol>
<li>字节顺序,是大端还是小端</li>
<li>使用哪种Unicode字符编码,例如是UTF-8还是UTF-16或者其他什么</li>
</ol>
<br />
BOM是可选的而非必须的,如果要用,必须在文本的开头。BOM一般使用在文本信息交换的场景下。<br />
BOM的编码如果出现在文本中间,会被解释为"zero-width non-breaking space",效果上等同于忽略了。<br />
上文已经解释了UTF-8下无大小端的区分,这时候如果还有BOM,那基本就是标记文本使用方应该用UTF-8进行字符解码。但实际上并没有必要。<br />
<br />
<h3>
4.字符集定义方法</h3>
上文我们可以明确的知道所有的字符串,要正确的进行解读,需要有一个正确的编码+解码方式,那当我们拿到一份文本的时候,如何才知道其正确的解码方式呢?<br />
有一些标准做法如下:<br />
1) Email<br />
使用Content-Type: text/plain; charset="UTF-8"作为表单的header<br />
<br />
2) Web<br />
最优的做法是在http header里面指定Content-Type: text/plain; charset="UTF-8",但是实际操作上web server可能处理大量的不同字符集的页面。实际的做法:<br />
在每个HTML页面<b>代码前面部分</b>加上类似如下的代码:<br />
<blockquote class="tr_bq">
<span style="background-color: white; border: 0px; box-sizing: border-box; color: #404040; font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;"><html><br style="box-sizing: border-box;" /><head></span><span style="background-color: white; border: 0px; box-sizing: border-box; color: #404040; font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 20px; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;"><<span class="start-tag" style="border: 0px; box-sizing: border-box; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">meta</span> <span class="attribute-name" style="border: 0px; box-sizing: border-box; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">http-equiv</span>=<span class="attribute-value" style="border: 0px; box-sizing: border-box; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">"Content-Type"</span> <span class="attribute-name" style="border: 0px; box-sizing: border-box; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">content</span>=<span class="attribute-value" style="border: 0px; box-sizing: border-box; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">"text/html; charset=utf-8"</span>></span></blockquote>
有人或许会疑惑HTML页面本身还没确认用什么编码解读,怎么依赖其内容了,还好上面这部分是基于ASCII字母,基本上所有编码都能读懂,在遇到生僻字之前,就基本能确认解码应该用怎样的字符集了!<br />
<br />
如果web浏览器在http header和HTML meta标签中都没找到字符集设置怎么处理?答案是浏览器比如IE会自行根据内容猜字符集。如你所料肯定不会非常靠谱的,所以不要纠结了,用规范的方式准没错!<br />
<br />
<br />
参考文献</div>
</div>
<ul>
<li>https://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html</li>
<li>https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84#.E5.9F.BA.E6.9C.AC.E5.A4.9A.E6.96.87.E7.A7.8D.E5.B9.B3.E9.9D.A2</li>
<li>https://en.wikipedia.org/wiki/Byte_order_mark</li>
<li>https://www.zhihu.com/question/20167122</li>
<li>http://www.qqxiuzi.cn/bianma/zifuji.php</li>
<li>http://stackoverflow.com/questions/701624/difference-between-big-endian-and-little-endian-byte-order</li>
<li>https://en.wikipedia.org/wiki/UTF-8</li>
<li>https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/</li>
</ul>
<br />
<div>
<br /></div>
<div>
<br /></div>
<br />
<div class="p1">
<br /></div>
</div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'PingFang SC'; color: #454545}
</style><br />
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px 'PingFang SC'; color: #454545}
span.s1 {font: 12.0px Helvetica}
</style>Carlhttp://www.blogger.com/profile/09568570315894174360noreply@blogger.com0tag:blogger.com,1999:blog-6735575389388224967.post-12536745697416415182017-04-20T10:04:00.000-07:002017-04-20T10:04:19.631-07:00工匠不知道 开篇期望自己有工匠精神,往往意味着选择了一条基本属于苦行僧的道路。但是苦还是乐,只有自己体会到才是最最真实的体验。<br />
<br />
最近看到猎豹移动CEO傅盛关于认知的四种境界:<br />
<br />
<ul>
<li>不知道自己不知道 95%</li>
<li>知道自己不知道 4%</li>
<li>知道自己知道 0.9%</li>
<li>不知道自己知道 0.1%</li>
</ul>
<div>
虽然这种话之前也有印象,但是也就一看,但是分析下来,发现我还是一个属于最低层次的大多数,活得不明不白。</div>
<div>
<br /></div>
<div>
非常认同认知能力造就了各自的不同,有人就是能够洞察世界而不卑不亢,而有人忙忙碌碌却一直浅薄无知。曾经不太相信人与人之间的差异有那么大,曾经相信人只要努努力就能成功,但是现在看来,人的认知水平如果不进取,真的很难跨越自己的层级,改变自己的人生。</div>
<div>
<br /></div>
<div>
怀揣着工匠精神,在没有其他产品的情况下,先打磨自己这个产品。产品思维,终局思维。。 这些新的理念汇总起来,先迈向“不知道"!</div>
<div>
<br /></div>
<div>
本博客记录思想,感悟和技术性文章,也可以转载,翻译等。不做日记和安排,Fighting!</div>
Carlhttp://www.blogger.com/profile/09568570315894174360noreply@blogger.com0