• 字符编码


    字符编码介绍

    1584013959777_thumb

    以下内容全是搬的:https://zhuanlan.zhihu.com/p/108805502

    太长了可以直接看最后总结

    1.什么是字符编码?

    人类在与计算机交互时,用的都是人类能读懂的字符,如中文字符、英文字符、日文字符等

    而计算机只能识别二进制数,详解如下。

    #二进制数即由0和1组成的数字,例如010010101010。计算机是基于电工作的,电的特性即高低电平,人类从逻辑层面将高电平对应为数字1,低电平对应为数字0,这直接决定了计算机可以识别的是由0和1组成的数字

    1584011416093_thumb1

    毫无疑问,由人类的字符到计算机中的数字,必须经历一个过程,翻译的过程必须参照一个特定的标准,该标准称之为字符编码表,该表上存放的就是字符与数字一一对应的关系。

    字符编码中的编码指的是翻译或者转换的意思,即将人能理解的字符翻译成计算机能识别的数字

    2.字符串的发展历史(三个重要的阶段)

    2.1 ASCII表

    ASCII表的特点: 1、只有英文字符与数字的一一对应关系 2、一个英文字符对应1Bytes,1Bytes=8bit,8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符.

    1584011866719_thumb1

    2.2 GBK

    为了让计算机能够识别中文和英文,中国人定制了GBK

    GBK表的特点: 1、只有中文字符、英文字符与数字的一一对应关系 2、一个英文字符对应1Bytes 一个中文字符对应2Bytes 补充说明: 1Bytes=8bit,8bit最多包含256个数字,可以对应256个字符,足够表示所有英文字符 2Bytes=16bit,16bit最多包含65536个数字,可以对应65536个字符,足够表示所有中文字符。

    每个国家都各自的字符,为让计算机能够识别自己国家的字符外加英文字符,各个国家都制定了自己的字符编码表。

    # Shift_JIS表的特点:
        1、只有日文字符、英文字符与数字的一一对应关系

    # Euc-kr表的特点:
        1、只有韩文字符、英文字符与数字的一一对应关系

    2.3 万国码

    unicode于1990年开始研发,1994年正式公布,具备两大特点:

    1. 存在所有语言中的所有字符与数字的一一对应关系,即兼容万国字符

    1. 与传统的字符编码的二进制数都有对应关系,详解如下

    1584012287445_thumb1

    文本编辑器输入任何字符都是最新存在于内存中,是unicode编码的,存放于硬盘中,则可以转换成任意其他编码,只要该编码可以支持相应的字符

    # 英文字符可以被ASCII识别
    英文字符--->unciode格式的数字--->ASCII格式的数字

    # 中文字符、英文字符可以被GBK识别
    中文字符、英文字符--->unicode格式的数字--->gbk格式的数字

    # 日文字符、英文字符可以被shift-JIS识别
    日文字符、英文字符--->unicode格式的数字--->shift-JIS格式的数字

    3.解码与编码

    3.1 编码

    由字符转换成内存中的unicode,以及由unicode转换成其他编码的过程,都称为编码encode

    1584012471221_thumb1

    3.2 解码

    由内存中的unicode转换成字符,以及由其他编码转换成unicode的过程,都称为解码decode

    1584012695430_thumb1

    4.utf-8的由来

    注意:如果保存到硬盘的是GBK格式二进制,当初用户输入的字符只能是中文或英文,同理如果保存到硬盘的是Shift_JIS格式二进制,当初用户输入的字符只能是日文或英文……如果我们输入的字符中包含多国字符,那么该如何处理?

    #多国字符—√—》内存(unicode格式的二进制)——X—》硬盘(GBK格式的二进制)

    #多国字符—√—》内存(unicode格式的二进制)——X—》硬盘(Shift_JIS格式的二进制)

    #多国字符—√—》内存(unicode格式的二进制)——√—》硬盘(???格式的二进制)

    理论上是可以将内存中unicode格式的二进制直接存放于硬盘中的,但由于unicode固定使用两个字节来存储一个字符,如果多国字符中包含大量的英文字符时,使用unicode格式存放会额外占用一倍空间(英文字符其实只需要用一个字节存放即可),然而空间占用并不是最致命的问题,最致命地是当我们由内存写入硬盘时会额外耗费一倍的时间,所以将内存中的unicode二进制写入硬盘或者基于网络传输时必须将其转换成一种精简的格式,这种格式即utf-8(全称Unicode Transformation Format,即unicode的转换格式)

    # 多国字符—√—》内存(unicode格式的二进制)——√—》硬盘(utf-8格式的二进制)

    1584013170238_thumb1

    五.字符编码的应用

    我们学习字符编码就是为了存取字符时不发生乱码问题:

    #1、内存中固定使用unicode无论输入任何字符都不会发生乱码

    #2、我们能够修改的是存/取硬盘的编码方式,如果编码设置不正确将会出现乱码问题。乱码问题分为两种:存乱了,读乱了

    #2.1 存乱了:如果用户输入的内容中包含中文和日文字符,如果单纯以shift_JIS存,日文可以正常写入硬盘,而由于中文字符在shift_jis中没有找到对应关系而导致存乱了

    #2.2 读乱了:如果硬盘中的数据是shift_JIS格式存储的,采GBK格式读入内存就读乱了

    总结:

    #1. 保证存的时候不乱:在由内存写入硬盘时,必须将编码格式设置为支持所输入字符的编码格式
    #2. 保证取的时候不乱:在由硬盘读入内存时,必须采用与写入硬盘时相同的编码格式

    6.python解释器执行文件的前两个阶段

    执行py文件的前两个阶段就是python解释器读文本文件的过程,与文本编辑读文本文件的前两个阶段没人任何区别,要保证读不乱码,则必须将python解释器读文件时采用的编码方式设置为文件当初写入硬盘时的编码格式,如果没有设置,python解释器则才用默认的编码方式,在python3中默认为utf-8,在python2中默认为ASCII,我们可以通过指定文件头来修改默认的编码

    # coding: 当初文件写入硬盘时采用的编码格式

    解释器会先用默认的编码方式读取文件的首行内容,由于首行是纯英文组成,而任何编码方式都可以识别英文字符。

    7.python解释器执行文件的第三个阶段

    设置文件头的作用是保证运行python程序的前两个阶段不乱码,经过前两个阶段后py文件的内容都会以unicode格式存放于内存中。

    在经历第三个阶段时开始识别python语法,当遇到特定的语法name = '上'(代码本身也都全都是unicode格式存的)时,需要申请内存空间来存储字符串'上',这就又涉及到应该以什么编码存储‘上’的问题了。

    在Python3中,字符串类的值都是使用unicode格式来存储

    由于Python2的盛行是早于unicode的,因此在Python2中是按照文件头指定的编码来存储字符串类型的值的(如果文件头中没有指定编码,那么解释器会按照它自己默认的编码方式来存储‘上’),所以,这就有可能导致乱码问题

    # coding:utf-8
    x = '上' # x的值为untf-8格式的二进制
    print(x) # 打印操作是将x的值,即utf-8格式的二进制交给终端,当终端收到后发现并不是unicode(只有unicode才与字符有对应关系),所以终端会执行操作:utf-8二进制---解码-->unicode格式的二进制,解码的过程终端会采用自己默认的编码,而在pycharm的终端默认编码为utf-8、windows下的cmd终端的默认编码为gbk,所以该打印操作在pycharm中显示正常,而在windows下的cmd中则乱码

    # 在windows下的cmd中运行效果如下
    C:UsersAdministrator>python2 E:aaa.py

    python2后推出了一种补救措施,就是在字符串类型前加u,则会将字符串类型强制存储unicode,这就与python3保持一致了,对于unicode格式无论丢给任何终端进行打印,都可以直接对应字符不会出现乱码问题。

    # coding:utf-8
    x = u'上' # 即便文件头为utf-8,x的值依然存成unicode

    8.字符串encode编码与decode解码的使用

    # 1、unicode格式------编码encode-------->其它编码格式
    >>> x='上' # 在python3在'上'被存成unicode
    >>> res=x.encode('utf-8')
    >>> res,type(res) # unicode编码成了utf-8格式,而编码的结果为bytes类型,可以当作直接当作二进制去使用
    (b'xe4xb8x8a', <class 'bytes'>)

    # 2、其它编码格式------解码decode-------->unicode格式
    >>> res.decode('utf-8')
    '上'

    9.总结

    结论:
        1、内存固定使用unicode,我们可以改变的是存入硬盘采用格式
            英文+汉字-》unicode-》gbk
            英文+日文-》unicode-》shift-jis
            万国字符》-unicode-》utf-8

        2、文本文件存取乱码问题
            存乱了:解决方法是,编码格式应该设置成支持文件内字符串的格式
            取乱了:解决方法是,文件是以什么编码格式存如硬盘的,就应该以什么编码格式读入内存
    image_thumb1
  • 相关阅读:
    倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何把FBD功能块转换成ST语言
    揭秘一个操作灰色关键词牟取暴利的案例
    [原创汉化] 价值990美元的顶级专业数据恢复软件O&O DiskRecovery 11(技术员版)汉化绿色版
    list集合如何对里面的元素进行排序
    jquery datables ajax分页后的点击事件无效是怎么回事
    阿里云自动快照有什么用,如何设置?
    php后台管理员权限相关表结构
    服务器上装了安全狗后远程链接不上怎么解决
    Ehcache配置参数简介
    Spring+EhCache缓存实例
  • 原文地址:https://www.cnblogs.com/bailongcaptain/p/12482321.html
Copyright © 2020-2023  润新知