• 编码方式


    几种编码方式:

    ASCII、ISO-8859-1、UTF-8、UTF-16、GBK

    ASCII


    它的全称是American Standard Code for Information Interchange(美国信息交换标准代码),是一个7位字符编码方案。下面是它的一张简图(来自http://www.asciitable.com/index/asciifull.gif):

    ASCII定义了128个字符,包括33个不可打印的控制字符(non-printing control characters)和95个可打印的字符。

    控制字符

    32以下的及最后一个127是所谓的控制字符。(0x00~0x1F以及0x7F)

    即上图最左边一列的32个字符及最右边一列最后的一个字符(DEL,删除)

    熟悉的有0x09(TAB,horizontal tab,水平制表符),0x0A(LF,line feed,’ ’换行符),0x0D(CR,carriage return,’ ’回车符),其它的很多现在已经是废弃不用了。

    关于回车换行(‘ ’),在屏幕还不普及的时代,结果输出经常是依赖于所谓的电传打印机,打印头沿着打印杆从左向右移动并打印出一个个字符,当碰到一个回车符时(CR,0x0D,’ ’),打印机就指示打印头重新回到最左边的位置上,这即是传统意义上的回车了。(你可以把打印头想像成一辆小车,回车即是退回原处,现代意义上的回车则通常包含回车与换行两个动作)

    回车符后常跟着一个换行符(LF,0x0A,’ ’),打印机收到换行符就会指示滚筒滚动,这样,打印头就对准了纸张上的新的一行。如果没有换行,新的打印输出就会重叠在上一行上,有时走纸不顺畅时也会造成这种后果。

    目前,在Windows系统上,回车键会产生两个字符CRLF,一起表示换行。Unix/Linux之类的则单独用LF表示换行,而苹果的Mac则单独用CR来表示换行。

    其它字符

    包括空格,字母,数字以及一些常见的标点符号等。

    关于空格(SPACE,图中第二列第一个,0x20),它没被归到控制字符类,当然,你可能会纠结它是否算可打印的。

    由于只定义了27=128个字符,用7bit即可完全编码,而一字节8bit的容量是256,所以一字节ASCII的编码最高位总是0,这为后来的编码方案兼容它带来的便利。

    ISO-8859-1


    ISO-8859-1又称Latin-1,是一个8位单字节字符集,它把ASCII的最高位也利用起来,并兼容了ASCII,新增的理论空间是128,但它并没有完全用完:(截图来自http://zh.wikipedia.org/wiki/ISO/IEC_8859-1

    image

    可以看到,新增部分也保留了前面的32个位置(中间绿色部分,0x80-0x9F),与前面的ASCII部分类似,所以实际只增加了128-32=96个,主要是西欧的一些字符,另外可以看到乘号(0xD7)和除号(0xF7)也被包含进来了。

    0x00-0x1F、0x7F、0x80-0x9F在此字符集中未有定义。(即图中的绿色部分)

    ISO-8859-1能与ASCII兼容,同时它的适用范围又较广,一些协议或软件把它作为一种缺省编码。

    Unicode


    世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

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

    Unicode 当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字严。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表。

    Unicode问题


    Unicode是一种符号集,规定了一个符号对应的二进制代码,但是却没有规定这种二进制代码的存储方式。

    比如,汉字严的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

    这里就有两个严重的问题,第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的

    它们造成的结果是:1)出现了 Unicode 的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示 Unicode。2)Unicode 在很长一段时间内无法推广,直到互联网的出现。

    UTF-8


    互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。

    UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
    UTF-8 的编码规则很简单,只有二条:

    • 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
    • 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

    下表总结了编码规则,字母x表示可用编码的位。

     

    跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

    下面,还是以汉字严为例,演示如何实现 UTF-8 编码。

    严的 Unicode 是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此严的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从严的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,严的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5

  • 相关阅读:
    c# winfrom 查看网络图片
    C# winfrom 读取txt文本内容
    c# winfrom 下载网页源代码
    c# winfrom 下载网络资源
    c# 换行符
    内存映射问题
    APUE 书中 toll 函数
    [P3387] 【模板】缩点
    [P5960] 【模板】差分约束算法
    [CF1442C] Graph Transpositions
  • 原文地址:https://www.cnblogs.com/langren1992/p/10149667.html
Copyright © 2020-2023  润新知