信息的编码·进制转换

二进制及其相关的进制转换与计算知识,是支撑起整个计算机科学的基础中的基础。从信息传输、加密解密、图像处理,到媒体编码、数据压缩、中继输出…二进制无处不在。二进制属于计算机科学中的「第一性原理」和基本常识之一,理解了二进制,就能串起计算机科学中很多看似不相关的领域。

1. ASCII、UrlEncode和Unicode等字符编码的原理

1.1 什么是文件

  • 计算机文件是一个存储在存储器上的数据序列,可以包含任何数据内容。 概念上,文件是数据的集合和抽象。
  • 用文件形式组织和表达数据更有效也更为灵活。 文件包括两种类型:文本文件和二进制文件。 文件本质上都是存储在存储器上的二进制数据。
  • `使用 HexEditor 可以以 16 进制的方式打开任何文件。

在这里插入图片描述

  • 特别的文本文件遵循统一的字符编码,在打开时,计算机会根据字符编码解析成编码表上对应的字符。
  • 二进制文件和文本文件本质上没有区别,只是没有统一的编码,需要根据特定的程序进行解析和运行。
  • 无论是文本文件还是二进制文件都可以用"文本文件方式"和"二进制文件方式"打开,打开后的操作不同。

1.2 字符编码

  • 计算机底层只能表示二进制信息,不能直接表示文字。计算机显示给我们看的文字可以看做是很小的一张张字符的图片。但如果文字都以图片进行存储和传输,图片体积非常大,从而效率会变得很低。所以计算机科学家将这些单个字符图片放到一个文件中,这个文件就是字体文件。再给每个字符一个编号,存储传输时就用字符的编号。这个编号表就是字符编码(简单这么理解)。
  • 文本文件存储的就是每个字符的编号,计算机在打开文本文件时,会根据指定的编码,去编码表中查询一个一个的字符,再渲染给用户。

1.2.1 ASCII码

因为历史原因,字符编码有很多。最先发明的是 ascii 码。
总共 127 个字符,因此使用一个字节(8 位二进制)来表示,也即是一个字符占一个字节的大小。
在这里插入图片描述

  • 在记事本中键入 abc123±*/,然后使用 HexEditor 打开后发现跟上面的编码表是一致的。
    在这里插入图片描述

1.2.2 GB2312

  • 可以看到 ascii 码里只有英文字母和常见字符,没有中文,以及世界上其他国家的文字。随着计算机的发展,各国都创建了自己国家的计算机字符编码。
  • 1980 年中国发布了 gb2312, GB2312 是一个简体中文字符集,由 6763 个常用汉字和 682 个全角的非汉字字符组成。
  • gb2312 使用两个字节表示一个汉字。
  • 通过字符串的 encode 方法可以根据字符编码进行编码
'中'.encode('gb2312')

// b’\xd6\xd0’

1.2.3 GBK

  • GB2312 的出现,基本满足了汉字的计算机处理需要,但对于人名、古汉语等方面出现的罕用字,GB 2312 不能处理,这导致了后来 GBK 及 GB18030 汉字字符集的出现。
  • GBK 即汉字内码扩展规范,K 为扩展的汉语拼音中“扩”字的声母。GBK 编码标准兼容 GB2312,共收录汉字 21003 个、符号 883 个,并提供 1894 个造字码位,简、繁体字融于一库。
  • gbk 也是使用两个字节表示一个汉字。
'中'.encode('gbk')

在这里插入图片描述

'囙'.encode('gb2312')

UnicodeEncodeError Traceback (most recent call last)

in
----> 1 ‘囙’.encode(‘gb2312’)
UnicodeEncodeError: ‘gb2312’ codec can’t encode character ‘\u56d9’ in position 0: illegal multibyte sequence
在这里插入图片描述

'囙'.encode('gbk')

b’\x87\xe0’
在这里插入图片描述

1.2.4 unicode

  • 世界上存在着多种编码方式,同一个编码值,在不同的编码体系里代表着不同的字。要想打开一个文本文件,不但要知道它的编码方式,还要安装有对应编码表,否则就可能无法读取或出现乱码。

  • 我上大学时玩电脑游戏最大的问题就是乱码。

  • 以日文的编码方式创建一个文本文件写入 やめて,然后用记事本打开会显示如下:
    在这里插入图片描述

  • 这个问题促使了 unicode 码的诞生。

  • unicode 将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。每个符号对应一个唯一的编码,乱码问题就不存在了。

  • Unicode 固然统一了编码方式,但是它的效率不高,比如 UCS-4(Unicode 的标准之一)规定用 4 个字节存储一个符号,那么每个英文字母前都必然有三个字节是 0,这对存储和传输来说都很耗资源。

  • 将之前写有 abc123±\ 的文件用记事本另存为 unicode 会发现文件的体积大了一倍。(本来应该是 4 倍,windows 做了优化)*
    在这里插入图片描述
    在这里插入图片描述

1.2.5 utf-8

为了提高 Unicode 的编码效率,于是就出现了 UTF-8 编码。UTF-8 可以根据不同的符号自动选择编码的长短。比如英文字母可以只用 1 个字节就够了。"汉"字的 Unicode 编码是 U+00006C49,然后把 U+00006C49 通过 UTF-8 编码器进行编码,最后输出的 UTF-8 编码是 E6B189。utf-8 中汉字使用 3 个字节存储。

'a'.encode('utf-8')

在这里插入图片描述
‘中’.encode(‘utf-8’)
b'\xe4\xb8\xad'
注意为了统一 python3 在内存中所有的字符都采用 unicode。

2 进制

2.1 常见进制

2.1.1 十进制

  • 日常生活中最常见的是十进制数,用十个不同的符号来表示:0、1、2、3、4、5、6、7、8、9。
    基为:10
  • 运算规则:逢十进一,借一当十
  • 在十进制数的后面加大写字母 “D” 以示区别。

2.1.2 二进制

  • 二进制数只有两个代码“0”和“1”,所有的数据都由它们的组合来实现。
  • 基为:2
  • 运算规则:“逢二进一,借一当二”的原则。
  • 在二进制数据后加英文字母 “B”

2.1.3 八进制

  • 使用的符号:0、1、2、3、4、5、6、7;
  • 运算规则:逢八进一;
  • 基为:8
  • 在八进制数据后加英文字母 “O”

2.1.4 十六进制

  • 使用的符号:采用0~9和A、B、C、D、E、F六个英文字母一起共十六个代码。
  • 运算规则:逢十六进一
  • 基为:16
  • 在十六进制数据后加英文字母 “H” 以示分别。

2.2 进制转换

2.2.1 N进制数转换成十进制数

由N进制数转换成十进制数的基本做法是,把N进制数首先写成加权系数展开式,然后按十进制加法规则求和。这种做法称为"按权相加"法。

  • 二进制中,各位的权为2n-1
  • 八进制中,各位的权为8n-1
  • 十进制中,各位的权为10n-1
  • 十六进制中,各位的权为10n-1

各数制中整数部分不同位的权为“基的n-1次方(n为数值所在的位数,n的最小值取1)”,小数部分不同位的权值为“基的-n次方,从左向右,每移一位,幂次减1”。

  • 二进制数的基数为2
    例:(1011.0011)2=1×24+0×23+1×22+1×21+0×20+0×2-1 +1×2-2+1×2-3
    =(11.1875)D
    例:(10010110)2=(150)D
    在这里插入图片描述

  • 八进制转换为十进制与二进制方法相同,只是八进制的基数为8
    (1011)8 = 1×83+0×82+1×81+1×80 = (521)10

  • 十六进制转换为十进制二进制方法相同,只是十六进制的基数为16
    (1011)16 = 1×163+0×162+1×161+1×160= (4113)10

2.2.2 十进制转换成N进制

整数部分(除基取余法)不断除以N直到商为0,再把各次的余数倒排;小数部分(乘基取整法)不断乘以N直到小数部分为0,再把各次的整数顺排。

  • 十进制转换为二进制
    十进制整数转换为二进制整数采用"除2取余,逆序排列"法。
    具体做法是:用十进制整数去除2,可以得到一个商和余数;再用商去除2,又会得到一个商和余数,如此进行,直到商为0时为止,逆序排列余数
    小数采用"乘2取整,顺序排列"法。
    具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到所要求的精度为止。
    【例1】将(236)D转换成二进制。转换过程如下图所示。
    111
    所以:(236)D=(11101100)B
    十进制转换成8进制、16进制,与转成2进制的方法相同,但基数是8或16!
2.2.2.1 十进制转换成八进制或十六进制有两种方法:
  • 间接法——把十进制转成二进制,然后再由二进制转成八进制或者十六进制。
  • 直接法——把十进制转八进制或者十六进制按照除8或者16取余,直到商为0为止。(具体用法如下图)
    在这里插入图片描述

2.2.3 二进制与八进制之间的转换:

2.2.3.1 八进制转二进制

八进制数通过除2取余法,得到二进制数,对每个八进制为3个二进制,不足时在最左边补零。
在这里插入图片描述

2.2.3.2 二进制转八进制

3位二进制数按权展开相加得到1位八进制数。(注意事项,3位二进制转成八进制是从右到左开始转换,不足时补0)。
在这里插入图片描述

2.2.4 二进制与十六进制之间的转换

2.2.4.1 十六进制转二进制

十六进制数通过除2取余法,得到二进制数,对每个十六进制为4个二进制,不足时在最左边补零。
在这里插入图片描述

2.2.4.2 二进制转十六进制

与二进制转八进制方法近似,八进制是取三合一,十六进制是取四合一。(注意事项,4位二进制转成十六进制是从右到左开始转换,不足时补0)。
在这里插入图片描述

2.3.5 十六进制与八进制之间的转换

八进制与十六进制之间的转换有两种方法

  • 第一种:他们之间的转换可以先转成二进制然后再相互转换。
  • 第二种:他们之间的转换可以先转成十进制然后再相互转换。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值