ASCII 碼錶
回憶上次內容
-
通過 help()可以從 python 命令行模式進入到幫助模式
- 通過 q 退出
-
ord(c)和 chr(i)
- 這是倆函數
-
這倆是一對,相反相成的
ord
通過字符找到對應的數字chr
通過數字找到對應的字符
字符
的本質是數字
-
Python 裏面的字符對應着一些數字
a
對應 97b
對應 98c
對應 99
- 可是,爲什麼是這樣的對應關係,誰規定的,必須的麼?🤔
小寫字母
#輸出a,b,c ord("a") ord("b") ord("c") #輸出z-a的數字差距,相對序號 ord("z")-ord("a") #輸出a的相對序號 ord("a")-ord("a")
- a、b、c 這些字符是挨着的
- 正好從0到25,總共26個數字🔢
- 對應數字也是挨着的
編碼規律
- 從 a-z 應該都是挨着的
- 26 個英文字母之間,數值差距是 25,說明都是挨着的
-
爲什麼是從 97 開始?
- 應該還有別的字符
- 除了小寫字母之外、大寫字母、數字、符號他們都是如何的分佈的呢?
- 我想把所有 ASCII 字符 0-127 全都打出來
- 可以麼?
遍歷範圍
for i in range(0,128): print(i,end=",")
- 我們先把0-127 挨牌兒捋一遍
- 然後如何找到數字對應的字符呢?
對應字符
- 通過數字找到對應的字符是chr
for i in range(0,128): print(hex(i),chr(i),sep=":",end=" ")
-
print(hex(i),chr(i),sep=":",end=" ")
-
hex(i)
- 輸出i的十六進制狀態
-
chr(i)
- 輸出i的字符狀態
-
sep=':'
- 分隔符爲冒號
-
end=" "
- 結束時輸出3個空格
-
- 結果如何呢?
結果
- 這不是很整齊啊
- 爲什麼在 0xa-0xc 好像換行很突然
- 後面可以看到字符和序號一一對應的關係
- 不過不是很明確
- 有什麼方式可以看起來更明確麼?
安裝 ASCII
sudo apt install ascii
- Dec 對應的是 10 進制數
- Hex 對應的是 16 進制數
- 後面的是具體字符
-
字符包括
- 控制
- 符號
- 英文大小寫字母
- 這樣就把各種字符和一個二進制數字對應起來了
- 這個 ASCII 什麼時候開始有的呢?
ASCII 碼錶
-
1967 年的時候就有了最初這個 ASCII 碼錶🔡
-
當時計算機用高電平和低電平分別表示 0 和 1
- 實際上計算機中所有的數據都是 0 和 1
- 這建立起了
字符
和二進制數
的映射關係
-
-
字符
和二進制數
的映射關係
如果不一致- 面對同一個二進制數 01010101
- 就會映射到不同的字符
- 人們看到不同的字符就認爲是亂碼
-
當時美國的工程師定義了一套編碼規則
-
ASCII
A
mericanS
tandardC
ode forI
nformationI
nterchange
- 美國信息交換標準代碼
-
由來
-
這標準是美國信息交換標準代碼是由美國國家標準學會制定的
- (American National Standard Institute , ANSI )
- 最初是美國標準
-
後來是國際標準化組織定爲國際標準
- (International Organization for Standardization, ISO)
- 稱爲 ISO 646 標準
-
最後一次更新則是在 1986 年
- 到目前爲止共定義了 128 個字符
解碼 ASCII
-
我們找到小寫的
a
-
先向上找到
110
- 這是他的
765
位 - 高三位
- 這是他的
-
再向左找到
0001
- 這是他的
4321
位 - 第四位
- 這是他的
- 在前面加一個
0
- 得到(
01100001
)2進制
- 對應着(
97
)10進制數
- 也就是(
0x61
)16進制數
- 剛好對應一個字節
-
對應關係
-
1 個 字節 byte
- 正好 8 個 bit 位
- 相當於 2 位 16 進制數
- 16 進制數 更容易讀出
- 十六進制數很適合輸出字節狀態
- 聽起來找到了字符和字節狀態之間的映射對應關係
- 我們能在遊樂場上驗證一下嗎?
遊樂場
- 進入 python3 幫助模式
-
我們可以查詢 hex
- hex 對應 hexadicimal 十六進制
- help(hex)
動手
#得到a的序號 ord("a") #輸出97對應的16進制形式 hex(97) #找到a對應的16進制形式數字對應的字符 hex(ord("a"))
-
0x61
就是十六進制的61
0x
是十六進制的前綴標誌
- 可是爲什麼 16 進制使用
0x
作爲前綴?
0x 前綴
-
x 的起源
- 0x 的 x 是取自 hex 的 x
-
0 的起源
- 變量名開頭不許是數字
- 0 開頭肯定是數字
- 但正常情況下寫數字不會用 0 開頭
- 這保證 0 開頭很容易和 10 進制區分開
-
在 C 語言之前的 B 語言用 0 開頭表示 8 進制
-
C 語言繼承了類似設定
- 0 開頭表示數字
- 0x 開頭表示 16 進制數
-
-
python 也繼續繼承
- 字符對應着數字
- 數字也可以轉化爲字符
-
字符和二進制數之間的關係其實是
- 編碼 encode
- 解碼 decode
編碼解碼
-
編碼
- 就是用預先規定的方法將文字、數字、其它對象編成數碼
- 將信息、數據轉換成規定的電脈衝信號
- 簡單來說就是給大白菜編個號
-
解碼是編碼的逆過程
- 用特定方法,把數碼還原成它所代表的內容
- 將電脈衝信號、光信號、無線電波等轉換成它所代表的信息、數據等的過程
- 簡單說就是掃條碼知道這個是一個大白菜並知道價格等
- 我們用python試試編碼解碼
encode和decode
- str(字符串)
'a'
encode(編碼)之後 爲 bytes(字節序列)b'\x61'
- bytes(字節序列)
b'\x61'
decode(解碼)之後爲 爲 str(字符串)'a'
- 編碼(encode) 和解碼(decode) 互爲逆運算
-
很像
- 字符(chr)和 序號(ord)
編碼解碼
- 可以先編碼再解碼
- 也可以先解碼再編碼
- 繞來繞去
- 也沒做神馬😁
- 掌握這個基礎是最起碼
- 基本功要練得硬橋硬馬
- 實戰方能穩紮穩打
- 否則以後各種亂碼
- 字節除了用十六進制顯示之外
- 還可以用二進制顯示麼?
bin(number)
- 這次我們來試試把數字轉化爲二進制形式
-
查詢 bin
- bin 對應 binary 二進制
動手
#得到a的序號 ord("a") #輸出97對應的16進制形式 bin(97) #找到a對應的十六進制形式 bin(ord("a"))
0b1100001
是二進制數1100001
-
0b
是 2 進制數的前綴標誌- 正如
0x
是 16 進制數的前綴標誌
- 正如
和 ASCII 表對比
- 驗證成功
- 這充分證明了我們用的確實是 ASCII 表!!!👏👏
- 廢話!🦧
- 我們會用 hex、bin 把 10 進制數轉化爲八進制、二進制形式
- 能把其他進制轉化回十進制麼?
其他進制 轉化爲回 10進制 int(number)
- 用的是 int
- 這個 int 什麼來歷?
- 我們 help()裏面去找找
大小字母差值
0x41-0x5A
這個範圍是大寫字母0x61-0x7A
這個範圍是小寫字母
#輸出a的ASCII嗎 ord("a") #輸出A的ASCII嗎 ord("A") #輸出大小寫之差 ord("a")-ord("A") #差值的16進制形式 hex(ord("a")-ord("A")) #差值的2進制形式 bin(ord("a")-ord("A"))
- 大寫字母和小寫字母相差(
32
)10進制
- 正好是(
0x20
)16進制
- 爲什麼不多不少
- 就差 0x20 呢?
- 怎麼那麼寸呢?🤔
ASCII 碼錶趣事
-
其實最初不是相差 0x20
- 這個 0x20 正好是一個二進制位
- 對應 b6 這個位
- 之前 ibm 的 EBCDIC 編碼並不是這樣的
- 那爲什麼要改成這樣子呢?
-
有了這種對應關係之後
- 做大小寫不敏感的字符串查找就快多了
-
這個 0x20 發生在 1963 年 5 月
- 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.
-
如果是大寫字母
- 修改1位之後,都變成小寫字母
- 然後直接查找就好了
ASCII 碼錶範圍
0x41-0x5A
這個範圍是大寫字母0x61-0x7A
這個範圍是小寫字母-
0x30-0x39
這個範圍是數字- 數字的編碼減去
0x30
正好得到數字本身
- 數字的編碼減去
- 我們再來看看 ASCII
ASCII
0x20-0x7F
之間有各種符號-
0x00-0x1F
之間的東西是什麼?- 目前還不知道
- 也許有一天可以進行進一步地探索
-
可以肯定都是
- 很多字符來自與更早之前的摩斯電碼
更早之前的摩斯電碼
-
ASCII 也不是從無到有的
- 在 ASCII 之前就有摩斯電碼
- 也是一種編碼方法
- 《oeasy 教您玩轉電路基礎》第 18 話介紹過
-
下圖是他的編碼表
- 分成長和短兩種信號,就是嘀和嗒
摩斯電碼通信規則
- 下圖是他的通信規則
- 三個斷確認本字符結束了
- 三個斷也就是字符之間的分隔符
- 錄入狀態並不是 0、1 兩種狀態
- 而是長、短、暫停三種狀態
- 爲什麼這樣編碼呢?
效率問題
-
編碼的規則是常用的字符點擊次數少
-
按照字符出現概率分配對應點擊數量
T
、E
出現頻率最高- 所以用一次點擊電鍵的數量
- 本質上是一棵霍夫曼樹
-
-
當時完全由人進行發射和接收
- 每個人發送數據的速度是不固定的
- 每個人接收數據的速度取決於發送人的發送速度
- 現查表是來不及的
- 需要熟悉編碼表和常用縮寫
-
這就是早期使用電來進行編碼的過程
- 我們現在回到 ASCII 碼
- 最後我們來總結一下
總結
-
數制可以轉化
- bin(n)可以把數字轉化爲
2進制
- hex(n)可以把數字轉化爲
16進制
- int(n)可以把數字轉化爲
10進制
- bin(n)可以把數字轉化爲
-
編碼和解碼可以轉化
- encode 編碼
- decode 解碼
-
ASCII 碼錶範圍
0x41-0x5A
這個範圍是大
寫字母0x61-0x7A
這個範圍是小
寫字母-
0x30-0x39
這個範圍是數字
- 數字的編碼減去
0x30
正好得到數字本身
- 數字的編碼減去
0x20-0x7F
之間有各種符號0x00-0x1F
之間的東西是什麼?🤔
- 我們下次再說