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

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

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

然后如何找到數(shù)字對應(yīng)的字符呢?
對應(yīng)字符
通過數(shù)字找到對應(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è)空格
分隔符為冒號
輸出i的字符狀態(tài)
輸出i的十六進(jìn)制狀態(tài)
hex(i)
chr(i)
sep=':'
end=" ? ?"
結(jié)果如何呢?
結(jié)果

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

這個(gè) ASCII 什么時(shí)候開始有的呢?
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)系
如果不一致面對同一個(gè)二進(jìn)制數(shù) 01010101
就會映射到不同的字符
人們看到不同的字符就認(rèn)為是亂碼
當(dāng)時(shí)美國的工程師定義了一套編碼規(guī)則
A
mericanS
tandardC
ode forI
nformationI
nterchangeASCII
美國信息交換標(biāo)準(zhǔn)代碼

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

我們找到小寫的
a
這是他的
4321
位第四位
這是他的
765
位高三位
先向上找到
110
再向左找到
0001
在前面加一個(gè)
0
得到(
01100001
)2進(jìn)制
對應(yīng)著(
97
)10進(jìn)制數(shù)
也就是(
0x61
)16進(jìn)制數(shù)
剛好對應(yīng)一個(gè)字節(jié)
對應(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)
聽起來找到了字符和字節(jié)狀態(tài)之間的映射對應(yīng)關(guān)系
我們能在游樂場上驗(yàn)證一下嗎?
游樂場
進(jìn)入 python3 幫助模式
我們可以查詢 hex
hex 對應(yīng) hexadicimal 十六進(jìn)制
help(hex)

動手
#得到a的序號
ord("a")
#輸出97對應(yīng)的16進(jìn)制形式
hex(97)
#找到a對應(yīng)的16進(jìn)制形式數(shù)字對應(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 語言繼承了類似設(shè)定
0 開頭表示數(shù)字
0x 開頭表示 16 進(jìn)制數(shù)
變量名開頭不許是數(shù)字
0 開頭肯定是數(shù)字
但正常情況下寫數(shù)字不會用 0 開頭
這保證 0 開頭很容易和 10 進(jìn)制區(qū)分開
在 C 語言之前的 B 語言用 0 開頭表示 8 進(jìn)制
python 也繼續(xù)繼承
編碼 encode
解碼 decode
字符對應(yīng)著數(shù)字
數(shù)字也可以轉(zhuǎn)化為字符
字符和二進(jìn)制數(shù)之間的關(guān)系其實(shí)是
編碼解碼
編碼
就是用預(yù)先規(guī)定的方法將文字、數(shù)字、其它對象編成數(shù)碼
將信息、數(shù)據(jù)轉(zhuǎn)換成規(guī)定的電脈沖信號
簡單來說就是給大白菜編個(gè)號

解碼是編碼的逆過程
用特定方法,把數(shù)碼還原成它所代表的內(nèi)容
將電脈沖信號、光信號、無線電波等轉(zhuǎn)換成它所代表的信息、數(shù)據(jù)等的過程
簡單說就是掃條碼知道這個(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)和 序號(ord)
編碼解碼
可以先編碼再解碼
也可以先解碼再編碼
繞來繞去
也沒做神馬??

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

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


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