zoukankan      html  css  js  c++  java
  • 学习PHP&MYSQL之——字符编码篇(一)

    一、字符编码简介

          计算机里,只能用二进制码记录文字、图片、图像、声音等媒体,要想将各式各样的媒体映射为简单的二进制编码(媒体 –> 01),就要将很多01根据多种变化的排列组合来表示这些媒体,这些排列组合的方法就成为了编码,文字、图片、声音都存在各式各样的编码。今天学习一下燕十八PHP公益培训课之——字符编码篇。

           1、ASCII

          最早的编码——ASCII编码,ASCII编码只能表示键盘上(A-Z、a-z、0-9、+-*/&^%)等不超过127个字符。

           1个字节有8位,可以表示256个字符,要表示ASCII码只需要7位就够了,所有最高位始终是0。

    0000 0000
    1111 1111    -->   256种值

            常用汉字3000多,1个字节不能表示,只能用2个字节表示,可以表示65535个字符,表示汉字够用了。

    0000 0000 0000 0000
    1111 1111 1111 1111  -->  共65535种值
          2、GB2312

          最早的中文字符集GB2312,GB2312不占用ASCII的0-127,两个字节组合来用,但是这样的组合就少了很多,例如:

    1xxx xxxx 1xxx xxxx  -->  [129 - 255] [129 - 255]  
    例如:
    130  140     97       95      144 233   (分组前)
          ↓          ↓         ↓           ↓
    [130 140]  [97]     [95]    [144 233]   (分组后)
          ↓          ↓         ↓           ↓
       [汉字]    [字母]   [字母]    [汉字]

         GB2312只收录了6763个汉字,基本满足了常用汉字的需求,但有些汉字没有收录。

         3、GBK

         GBK编码完全兼容GB2312,GBK还是双字节,理论上第2字节不再局限于129-255,如果第1字节大于128,则带下一个字节组成一个汉字,如果第1个小于128,就直接转ASCII。例如:

    1xxx xxxx xxxx xxxx  -->   [129 - 255][0 - 255]
    例如:
    133  22    63      199  22     (分组前)
         ↓         ↓           ↓
    [133 22]  [63]    [199 22]    (分组后)
         ↓         ↓           ↓ 
      [汉字]   [字母]     [汉字]

           实际上,GBK的编码方式,有单字节和双字节编码组成,00-7F范围内只占一位,和ASCII保持一致,此范围内阉割上说有96个字符和32个控制符号。之后的双字节中,前一字节是双字节的第一位。总体上说第一字节的范围是81-FE(也就是不含80和FF),第二字节的一部分领域在40-7E,其他领域在80-FE。收录汉字21003个、符号883个、并提供1894个造字码位。

          4、Unicode和UTF-8

         Unicode是一个世界通用的码表,它占4个字节,包含232,共40多亿字符,但常用的集中在前65535个标号里,2个字节就够用了。Unicode只负责分配编号,而且都用4个字节来分配编号,而真正的实现方式成为Unicode转换格式(Unicode Transformation Format,简称为UTF)

          例如,如果一个仅包含基本7位ASCII字符的Unicode文件,如果每个字符都使用2字节的原Unicode编码传输,其第一字节的8位始终为0,这造成了较大的浪费。对于这种情况,可以使用UTF-8编码,这是一种变长编码。它根据一定的算法减小浪费,具体实现如下:

    Unicode根据一定算法转为UTF-8
    例如:
    0000 0000 0000 0000 0000 0000 0000 0041 –> A    (Unicode)

    0000 0041 –> A                                                 (UTF-8)

        Unicode与UTF-8的关系就像原文件与压缩文件的关系,具体如下:

    UCS-4编码

    UTF-8字节流

    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+00040000 - U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

         UTF-8编码是根据第一字节的高位来决定一个字符占几个字节的,基本规律是:

    第一字节高位

    占用字节数

    0 1个字节
    11 2个字节
    111 3个字节
    1111 4个字节
    11111 5个字节
    111111 6个字节

    二、乱码的形成

       乱码产生的原因:

    • 解码时与实际编码不一致(可修复)。
    • 传输过程中,编码不一致,导致字节丢失(不可修复)。

       1、解码时与实际编码不一致情况

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
      <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
      <!--  当charset为utf-8时,文档又另存为ansi(GBK)格式,网页就会产生乱码  -->!-- --》
      <title>乱码测试</title>
     </head>
     <body>
      测试
     </body>
    </html>

      2、传输过程中,编码不一致,导致字节丢失(这种情况将在下一篇见到)


    燕十八php公益课,网址:http://zixue.it/ ,YY频道:88354001,YY群:7840433

  • 相关阅读:
    【转载】Android应用框架及常用工具类总结
    【Android】Android开发规范的一点小体会
    【Android】解决Android的ListView控件滚动时背景变黑
    【Android】侧边栏SlidingMenu
    【Android】解决RadioButton+FragmentPagerAdapter+Fragment切换页面数据加载的问题
    【Android】ListView动态视图显示不全
    Android编码规范
    【Android】两个日期相差几天和两个日期比较大小
    Linux基础之快照克隆、Xshell优化、Linux历史
    Android APP打包时,出错:"XXX" is not translated in "af" (Afrikaans), "am" (Amharic)
  • 原文地址:https://www.cnblogs.com/giantpanda/p/2752683.html
Copyright © 2011-2022 走看看