计算机编码和解码

(1)理解编码和解码

虽然我们接触到的数据是各种字符等,但计算机存储数据是用二进制数据的方式。二进制数据是由0和1两个数字组成的数据,是计算机最基本的存储单位。计算机中的所有数据都以二进制形式进行存储和处理。计算机的存储在物理上是二进制的,任何一个数据都是用一堆0和1来表示。一个0或1表示一个比特(bit)。在计算机中一个二进制称为1比特(bit),八位的二进制称为1字节(byte)。

字符转化为二进制数据的过程:一个字符先根据某种编码方式转化为对应的数字,然后这个数字再转化为二进制数字(为了操作方便,通常转化为16进制传给计算机)。这个转换过程就是编码。

按不同的转换规则就涉及到不同的编码方式。比如字符串"你好,中国",按"gbk"编码方式对应的二进制数据为

bash 复制代码
b'\xc4\xe3\xba\xc3\xa3\xac\xd6\xd0\xb9\xfa'

其中\x表示16进制数,c4表示大小,占一个字节

解码就是将二进制数据翻译为我们能理解的字符。

(2)乱码怎么来的

如果编码时按A规则,解码时按B规则,就可能出现乱码,所以编码和解码一般需要保持统一。

(3)常见编码

ASCII码(1字节)

ASCII码是American Standard Code for Information Interchange的缩写,美国信息交换标准码。

计算机最早是美国人发明的,英文中只需要使用英文字母、数字、特殊符号以及计算机的控制符。当时在他们看来,计算机中字符只需要100多个就够了,因此他们选择使用7位的二进制来表示字符的编码。用0到127来对应键盘上的128个字符。

十进制中,数字 0 的 ASCII 码是 48,字母 A 的 ASCII 码是 65,字母 a 的 ASCII 码是 97

任何小写字母的 ASCII 码减去其大写字母的 ASCII 码都是 32。

python中 ASCII码值与字符的转化函数

python 复制代码
if __name__ == "__main__":
    # ASCII码值转字符
    print(chr(49))  # 对应字符1
    print(chr(50))  # 对应字符2
    # 字符转ASCII码值
    print(ord('A'))  # 65
    print(ord('x'))  # 120

后面由于欧洲比如法语等,128个字符不够用,ASCII扩展到0-255,具体细节就不说了。因此一个ASCII码占用8位,也就是占用1字节内存大小。

ANSI码

在不同的操作系统中,ANSI码对应不同的编码:

  • 在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;
  • 在英文Windows操作系统中,ANSI 编码代表 ASCII编码;
  • 在繁体中文Windows操作系统中,ANSI编码代表Big5;
  • 在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。

Unicode编码(4字节)

前面讲了ASCII码的知识,大家看出来,英文在电脑中的编码是没问题了。但是计算机走向全世界时,问题来了,电脑中如何表示其他各国的语言呢?我们暂且不说别的国家的文字,就中文里面使用的汉字就多达几万个,再加上俄语的西里尔字母、阿拉伯语的字母等等。

为了保持全世界语言在计算机中统一的表示,人们制定了Unicode(万国码)的标准,确保了世界上所有的语言都能够使用统一的标准编码。

Unicode最早使用的是2个字节,奈何字符数量实在太多,最后扩展成了4个字节。

Python 3中字符串类型中的字符使用的就是Unicode。

Unicode码称做统一码,以"\u"开始,从"\u0000"到"\uFFFF"

python中查看 Unicode码值对应的字符

python 复制代码
python中查看Unicode码值对应的字符
if __name__ == "__main__":
    print("\u6B22")  # 欢
    print("\u8FCE")  # 迎
    print("\u3434")  # 㐴

Unicode编码产生前各国的编码

Unicode是1991年开始制定的,在制定Unicode之前,各个国家都制定了各自的字符编码,以保证字符在计算机中的正常显示。如中国大陆的gb2312、香港台湾地区的BIG5、日本的SHIFT-JIS等等。使用不同的编码看字符会出现"乱码"现象。

GBK编码

中国大陆的gb2312和香港台湾地区的BIG5合并以后形成一个中文字符编码的超集,名字叫GBK。目前我们使用的Windows操作系统简体中文版中仍然使用的是GBK编码。

UTF-8编码

Unicode虽然很好,但是却有很大的问题。英文字母使用ASCII码原本只要一个字节就能表示的,使用Unicode却需要4个字节,白白浪费了空间。尤其是在网络传输时,白白浪费了网络带宽。于是UTF-8编码方式就诞生了。

UTF-8是一种针对Unicode的可变长度字符编码,它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容。在UTF-8中,英文字符仍然是1个字节,汉字占几个字节是不确定度,有可能2个字节、3个字节或者4个字节。

(4)python编码和解码接口

encode和decode函数

python 复制代码
if __name__ == "__main__":
    # 1.编码函数 encode
    data_str = "你好,中国"
    data_bin = data_str.encode("gbk")
    print(data_bin)  # b'\xc4\xe3\xba\xc3\xa3\xac\xd6\xd0\xb9\xfa'
    
    # 2.解码函数
    result = data_bin.decode("gbk")
    print(result)  # 你好,中国
    
    # 3.如果编码和解码用不同的方式则可能会出错
    # result = data_bin.decode("utf-8")
    # 比如data_bin是按gbk编码,这里却用utf-8解码,就会报错
    # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc4 in position 0: invalid continuation byte
    
    # 4.解码失败,强行解码
    result = data_bin.decode("utf-8", "ignore")
    print(result)  # ãй  
    # 可以看到结果不对,所以还是不要强行解码的好,不过有时也需要强行解码

bytes函数

python 复制代码
if __name__ == "__main__":
    # 编码也可以用bytes 函数,不过必须指明编码方式
    # 1.对中文字符进行编码
    data = "你好,中国"
    res1 = bytes(data, "gbk")
    res2 = bytes(data, "utf-8")
    print(res1)  # b'\xc4\xe3\xba\xc3\xa3\xac\xd6\xd0\xb9\xfa'
    print(res2)  # b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\xad\xe5\x9b\xbd'
    print(res1.decode("gbk"))   # 你好,中国
    print(res2.decode("utf-8"))  # 你好,中国
    
    # 如果内容是纯英文字母和数字,可以直接在字符串的引号前加字母b,就可以将变量类型定义为二进制序列类型
    data = b'hello world'
    print(data.decode("utf-8"))  # hello world
    print(data.decode("gbk"))    # hello world
    
    # 2.对纯英文字母和数字的字符进行编码,等价于直接在字符串的引号前加字母b,占一个字节
    x = bytes('0', 'utf-8')
    print(x)   # b'0'
    x = bytes('0', 'gbk')
    print(x)   # b'0'
    y = bytes('A', 'utf-8')
    print(y)   # b'b'A'
    y = bytes('A', 'gbk')
    print(y)   # b'b'A'

(5)gbk和utf-8编码方式下英文字母和汉字字符占几个字节

先说验证结论:

  • 对于英文字母都是占一个字节
  • 对于汉字字符:
    • utf-8编码方式下一个汉字占3个字节(前面两个字符表示汉字,最后那个字符表示结束)
    • gbk编码方式下一个汉字占2个字节
python 复制代码
if __name__ == "__main__":
    # 1.对于英文字母都是占一个字节
    data = "y"
    print(data.encode("utf-8"))  # b'y'
    print(data.encode("gbk"))    # b'y'
    
    # 2.对于汉字字符
    # utf-8编码方式下一个汉字占3个字节(前面两个字符表示汉字,最后那个字符表示结束)
    # gbk编码方式下一个汉字占2个字节
    data = "年"
    print(data.encode("utf-8"))  # b'\xe5\xb9\xb4'
    print(data.encode("gbk"))  # b'\xc4\xea'
    data = "过年"
    print(data.encode("utf-8"))  # b'\xe8\xbf\x87\xe5\xb9\xb4'
    print(data.encode("gbk"))  # b'\xb9\xfd\xc4\xea'

end

相关推荐
百锦再13 分钟前
微信小程序学习基础:从入门到精通
前端·vue.js·python·学习·微信小程序·小程序·pdf
PWRJOY39 分钟前
Flask 路由跳转机制:url_for生成动态URL、redirect页面重定向
后端·python·flask
熊猫在哪1 小时前
野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(四)安装RKNN Toolkit2
人工智能·python·嵌入式硬件·深度学习·神经网络·目标检测·机器学习
liweiweili1261 小时前
sqlalchemy常用的数据类型
数据库·python
老唐7771 小时前
PyTorch的基本操作
人工智能·pytorch·python·深度学习·神经网络·机器学习·计算机视觉
engchina1 小时前
使用Python和FastAPI构建网站爬虫:Oncolo医疗文章抓取实战
爬虫·python·fastapi
kkkkkkkkk_12011 小时前
【框架安装】win10 配置安装GPU加速的tensorflow和keras教程
人工智能·python·tensorflow·keras
测试19981 小时前
如何使用Selenium进行网页自动化?
自动化测试·软件测试·python·selenium·测试工具·职场和发展·测试用例
真智AI1 小时前
如何用 Qwen1.5-7B-Chat 模型打造高效轻量的 Python 智能助手(详细实操指南)
开发语言·python
不知道写什么的作者1 小时前
Python安全密码生成器:告别弱密码的最佳实践
开发语言·python