oeasy教您玩轉(zhuǎn)python - 008 - # ascii碼表
ASCII 碼表
回憶上次內(nèi)容
通過(guò) help()可以從 python 命令行模式進(jìn)入到幫助模式
通過(guò) q 退出
ord(c)和 chr(i)
ord
通過(guò)字符找到對(duì)應(yīng)的數(shù)字chr
通過(guò)數(shù)字找到對(duì)應(yīng)的字符這是倆函數(shù)
這倆是一對(duì),相反相成的
字符
的本質(zhì)是數(shù)字
Python 里面的字符對(duì)應(yīng)著一些數(shù)字
a
對(duì)應(yīng) 97b
對(duì)應(yīng) 98c
對(duì)應(yīng) 99可是,為什么是這樣的對(duì)應(yīng)關(guān)系,誰(shuí)規(guī)定的,必須的么???
小寫(xiě)字母
#輸出a,b,c
ord("a")
ord("b")
ord("c")
#輸出z-a的數(shù)字差距,相對(duì)序號(hào)
ord("z")-ord("a")
#輸出a的相對(duì)序號(hào)
ord("a")-ord("a")
a、b、c 這些字符是挨著的
正好從0到25,總共26個(gè)數(shù)字??
對(duì)應(yīng)數(shù)字也是挨著的

編碼規(guī)律
從 a-z 應(yīng)該都是挨著的
26 個(gè)英文字母之間,數(shù)值差距是 25,說(shuō)明都是挨著的
為什么是從 97 開(kāi)始?
應(yīng)該還有別的字符
除了小寫(xiě)字母之外、大寫(xiě)字母、數(shù)字、符號(hào)他們都是如何的分布的呢?
我想把所有 ASCII 字符 0-127 全都打出來(lái)
可以么?
遍歷范圍

for i in range(0,128): ? ?
????????print(i,end=",")
我們先把0-127 挨牌兒捋一遍

然后如何找到數(shù)字對(duì)應(yīng)的字符呢?
對(duì)應(yīng)字符
通過(guò)數(shù)字找到對(duì)應(yīng)的字符是chr

for i in range(0,128): ? ?
????print(hex(i),chr(i),sep=":",end=" ? ?")
print(hex(i),chr(i),sep=":",end=" ? ?")
結(jié)束時(shí)輸出3個(gè)空格
分隔符為冒號(hào)
輸出i的字符狀態(tài)
輸出i的十六進(jìn)制狀態(tài)
hex(i)
chr(i)
sep=':'
end=" ? ?"
結(jié)果如何呢?
結(jié)果

這不是很整齊啊
為什么在 0xa-0xc 好像換行很突然
后面可以看到字符和序號(hào)一一對(duì)應(yīng)的關(guān)系
不過(guò)不是很明確
有什么方式可以看起來(lái)更明確么?
安裝 ASCII
sudo apt install asciiDec 對(duì)應(yīng)的是 10 進(jìn)制數(shù)
Hex 對(duì)應(yīng)的是 16 進(jìn)制數(shù)
后面的是具體字符
字符包括
控制
符號(hào)
英文大小寫(xiě)字母
這樣就把各種字符和一個(gè)二進(jìn)制數(shù)字對(duì)應(yīng)起來(lái)了

這個(gè) ASCII 什么時(shí)候開(kāi)始有的呢?
ASCII 碼表
1967 年的時(shí)候就有了最初這個(gè) ASCII 碼表??
實(shí)際上計(jì)算機(jī)中所有的數(shù)據(jù)都是 0 和 1
當(dāng)時(shí)計(jì)算機(jī)用高電平和低電平分別表示 0 和 1
這建立起了
字符
和二進(jìn)制數(shù)
的映射關(guān)系
字符
和二進(jìn)制數(shù)
的映射關(guān)系
如果不一致面對(duì)同一個(gè)二進(jìn)制數(shù) 01010101
就會(huì)映射到不同的字符
人們看到不同的字符就認(rèn)為是亂碼
當(dāng)時(shí)美國(guó)的工程師定義了一套編碼規(guī)則
A
mericanS
tandardC
ode forI
nformationI
nterchangeASCII
美國(guó)信息交換標(biāo)準(zhǔn)代碼

由來(lái)
這標(biāo)準(zhǔn)是美國(guó)信息交換標(biāo)準(zhǔn)代碼是由美國(guó)國(guó)家標(biāo)準(zhǔn)學(xué)會(huì)制定的
(American National Standard Institute , ANSI )
最初是美國(guó)標(biāo)準(zhǔn)
后來(lái)是國(guó)際標(biāo)準(zhǔn)化組織定為國(guó)際標(biāo)準(zhǔn)
(International Organization for Standardization, ISO)
稱(chēng)為 ISO 646 標(biāo)準(zhǔn)
最后一次更新則是在 1986 年
到目前為止共定義了 128 個(gè)字符
解碼 ASCII

我們找到小寫(xiě)的
a
這是他的
4321
位第四位
這是他的
765
位高三位
先向上找到
110
再向左找到
0001
在前面加一個(gè)
0
得到(
01100001
)2進(jìn)制
對(duì)應(yīng)著(
97
)10進(jìn)制數(shù)
也就是(
0x61
)16進(jìn)制數(shù)
剛好對(duì)應(yīng)一個(gè)字節(jié)
對(duì)應(yīng)關(guān)系
1 個(gè) 字節(jié) byte
正好 8 個(gè) bit 位
相當(dāng)于 2 位 16 進(jìn)制數(shù)
16 進(jìn)制數(shù) 更容易讀出
十六進(jìn)制數(shù)很適合輸出字節(jié)狀態(tài)
聽(tīng)起來(lái)找到了字符和字節(jié)狀態(tài)之間的映射對(duì)應(yīng)關(guān)系
我們能在游樂(lè)場(chǎng)上驗(yàn)證一下嗎?
游樂(lè)場(chǎng)
進(jìn)入 python3 幫助模式
我們可以查詢 hex
hex 對(duì)應(yīng) hexadicimal 十六進(jìn)制
help(hex)

動(dòng)手
#得到a的序號(hào)
ord("a")
#輸出97對(duì)應(yīng)的16進(jìn)制形式
hex(97)
#找到a對(duì)應(yīng)的16進(jìn)制形式數(shù)字對(duì)應(yīng)的字符
????hex(ord("a"))
0x61
就是十六進(jìn)制的61
0x
是十六進(jìn)制的前綴標(biāo)志

可是為什么 16 進(jìn)制使用
0x
作為前綴?
0x 前綴
x 的起源
0x 的 x 是取自 hex 的 x

0 的起源
C 語(yǔ)言繼承了類(lèi)似設(shè)定
0 開(kāi)頭表示數(shù)字
0x 開(kāi)頭表示 16 進(jìn)制數(shù)
變量名開(kāi)頭不許是數(shù)字
0 開(kāi)頭肯定是數(shù)字
但正常情況下寫(xiě)數(shù)字不會(huì)用 0 開(kāi)頭
這保證 0 開(kāi)頭很容易和 10 進(jìn)制區(qū)分開(kāi)
在 C 語(yǔ)言之前的 B 語(yǔ)言用 0 開(kāi)頭表示 8 進(jìn)制
python 也繼續(xù)繼承
編碼 encode
解碼 decode
字符對(duì)應(yīng)著數(shù)字
數(shù)字也可以轉(zhuǎn)化為字符
字符和二進(jìn)制數(shù)之間的關(guān)系其實(shí)是
編碼解碼
編碼
就是用預(yù)先規(guī)定的方法將文字、數(shù)字、其它對(duì)象編成數(shù)碼
將信息、數(shù)據(jù)轉(zhuǎn)換成規(guī)定的電脈沖信號(hào)
簡(jiǎn)單來(lái)說(shuō)就是給大白菜編個(gè)號(hào)

解碼是編碼的逆過(guò)程
用特定方法,把數(shù)碼還原成它所代表的內(nèi)容
將電脈沖信號(hào)、光信號(hào)、無(wú)線電波等轉(zhuǎn)換成它所代表的信息、數(shù)據(jù)等的過(guò)程
簡(jiǎn)單說(shuō)就是掃條碼知道這個(gè)是一個(gè)大白菜并知道價(jià)格等

我們用python試試編碼解碼
encode和decode

str(字符串)
'a'
encode(編碼)之后 為 bytes(字節(jié)序列)b'\x61'

bytes(字節(jié)序列)
b'\x61'
decode(解碼)之后為 為 str(字符串)'a'
編碼(encode) 和解碼(decode) 互為逆運(yùn)算
很像
字符(chr)和 序號(hào)(ord)
編碼解碼
可以先編碼再解碼
也可以先解碼再編碼
繞來(lái)繞去
也沒(méi)做神馬??

掌握這個(gè)基礎(chǔ)是最起碼
基本功要練得硬橋硬馬
實(shí)戰(zhàn)方能穩(wěn)扎穩(wěn)打
否則以后各種亂碼

字節(jié)除了用十六進(jìn)制顯示之外
還可以用二進(jìn)制顯示么?
bin(number)
這次我們來(lái)試試把數(shù)字轉(zhuǎn)化為二進(jìn)制形式
查詢 bin
bin 對(duì)應(yīng) binary 二進(jìn)制


動(dòng)手
#得到a的序號(hào)ord("a")#輸出97對(duì)應(yīng)的16進(jìn)制形式bin(97)#找到a對(duì)應(yīng)的十六進(jìn)制形式bin(ord("a"))0b1100001
是二進(jìn)制數(shù)1100001
0b
是 2 進(jìn)制數(shù)的前綴標(biāo)志正如
0x
是 16 進(jìn)制數(shù)的前綴標(biāo)志

和 ASCII 表對(duì)比
驗(yàn)證成功
這充分證明了我們用的確實(shí)是 ASCII 表!?。????
廢話!??
我們會(huì)用 hex、bin 把 10 進(jìn)制數(shù)轉(zhuǎn)化為八進(jìn)制、二進(jìn)制形式
能把其他進(jìn)制轉(zhuǎn)化回十進(jìn)制么?
其他進(jìn)制 轉(zhuǎn)化為回 10進(jìn)制 int(number)
用的是 int
這個(gè) int 什么來(lái)歷?
我們 help()里面去找找
大小字母差值
0x41-0x5A
這個(gè)范圍是大寫(xiě)字母0x61-0x7A
這個(gè)范圍是小寫(xiě)字母
#輸出a的ASCII碼
ord("a")#輸出A的ASCII碼
ord("A")
#輸出大小寫(xiě)之差
ord("a")-ord("A")
#差值的16進(jìn)制形式
hex(ord("a")-ord("A"))
#差值的2進(jìn)制形式
bin(ord("a")-ord("A"))
大寫(xiě)字母和小寫(xiě)字母相差(
32
)10進(jìn)制
正好是(
0x20
)16進(jìn)制
為什么不多不少
就差 0x20 呢?
怎么那么寸呢???
ASCII 碼表趣事
其實(shí)最初不是相差 0x20
這個(gè) 0x20 正好是一個(gè)二進(jìn)制位
對(duì)應(yīng) b6 這個(gè)位
之前 ibm 的 EBCDIC 編碼并不是這樣的
那為什么要改成這樣子呢?
有了這種對(duì)應(yīng)關(guān)系之后
修改1位之后,都變成小寫(xiě)字母
然后直接查找就好了
The X3.2.4 task group voted its approval for the change to ASCII at its May 1963 meeting.
Locating the lowercase letters in columns 6 and 7 caused the characters to differ in bit pattern from the upper case by a single bit, which simplified case-insensitive character matching and the construction of keyboards and printers.
做大小寫(xiě)不敏感的字符串查找就快多了
這個(gè) 0x20 發(fā)生在 1963 年 5 月
ASCII 碼表范圍
0x41-0x5A
這個(gè)范圍是大寫(xiě)字母0x61-0x7A
這個(gè)范圍是小寫(xiě)字母0x30-0x39
這個(gè)范圍是數(shù)字數(shù)字的編碼減去
0x30
正好得到數(shù)字本身
我們?cè)賮?lái)看看 ASCII
ASCII
0x20-0x7F
之間有各種符號(hào)0x00-0x1F
之間的東西是什么?目前還不知道
也許有一天可以進(jìn)行進(jìn)一步地探索
可以肯定都是
很多字符來(lái)自與更早之前的摩斯電碼
更早之前的摩斯電碼
ASCII 也不是從無(wú)到有的
在 ASCII 之前就有摩斯電碼
也是一種編碼方法
《oeasy 教您玩轉(zhuǎn)電路基礎(chǔ)》第 18 話介紹過(guò)
下圖是他的編碼表
分成長(zhǎng)和短兩種信號(hào),就是嘀和嗒
摩斯電碼通信規(guī)則
下圖是他的通信規(guī)則
三個(gè)斷確認(rèn)本字符結(jié)束了
三個(gè)斷也就是字符之間的分隔符
錄入狀態(tài)并不是 0、1 兩種狀態(tài)
而是長(zhǎng)、短、暫停三種狀態(tài)
為什么這樣編碼呢?
效率問(wèn)題
編碼的規(guī)則是常用的字符點(diǎn)擊次數(shù)少
T
、E
出現(xiàn)頻率最高所以用一次點(diǎn)擊電鍵的數(shù)量
按照字符出現(xiàn)概率分配對(duì)應(yīng)點(diǎn)擊數(shù)量
本質(zhì)上是一棵霍夫曼樹(shù)
當(dāng)時(shí)完全由人進(jìn)行發(fā)射和接收
每個(gè)人發(fā)送數(shù)據(jù)的速度是不固定的
每個(gè)人接收數(shù)據(jù)的速度取決于發(fā)送人的發(fā)送速度
現(xiàn)查表是來(lái)不及的
需要熟悉編碼表和常用縮寫(xiě)
這就是早期使用電來(lái)進(jìn)行編碼的過(guò)程
我們現(xiàn)在回到 ASCII 碼
最后我們來(lái)總結(jié)一下
總結(jié)
數(shù)制可以轉(zhuǎn)化
bin(n)可以把數(shù)字轉(zhuǎn)化為
2進(jìn)制
hex(n)可以把數(shù)字轉(zhuǎn)化為
16進(jìn)制
int(n)可以把數(shù)字轉(zhuǎn)化為
10進(jìn)制
編碼和解碼可以轉(zhuǎn)化
encode 編碼
decode 解碼
ASCII 碼表范圍
數(shù)字的編碼減去
0x30
正好得到數(shù)字本身0x41-0x5A
這個(gè)范圍是大
寫(xiě)字母0x61-0x7A
這個(gè)范圍是小
寫(xiě)字母0x30-0x39
這個(gè)范圍是數(shù)字
0x20-0x7F
之間有各種符號(hào)0x00-0x1F
之間的東西是什么???我們下次再說(shuō)