比特 bit 字節 byte ASCII碼 Unicode UTF 32 UTF 8 傻傻分不清楚
"1個字節是8個比特,1個字母是1個字節,1個漢字是2個字節"
- 上面這句話很多人都看過聽過
- 但大部分人都不知道為什么 (例如前兩天的我)
- 這句話在某些規定下其實是不正確的
bit
- 中文:比特
- 表示0或1
- 計算機中最小的單位
byte
- 中文:字節
- 1byte==8bit 表示8個比特(為什么不是2個或者4個 后面解答)
插一句 比特幣 字節跳動 名字取的真好
ASCII碼
- 美國制定的一套讓計算機識別、保存、讀取字符的標准
- 字符定義: 數字'7' 字母'a' 操作字符(刪除 確定)
- 一共有128個字符 每個字符都有唯一的編碼 查看ascii.pdf
- 計算機中最小的單位是比特所以我們用比特來存儲
- 那么需要多少個比特來存一個字符呢?
- 2比特 最多保存 4個數據 00 01 10 11
- 4比特 最多保存16個數據 0000 0001 0010 0011 ...... 1111
- 7比特 最多保存128個數據 0000000 0000001 0000010 0000011 ...... 1111111
- 8比特 最多保存255個數據 00000000 00000001 00000010 00000011 ...... 11111111
- 其實7bit就可以保存128個字符 但是最后還是用8比特 因為當時用第八位來作為奇偶校驗位(奇偶校驗位現在沒用)
- byte的概念最早是用來表示一個"字" 也就是char 最后通俗約定 8bit表示1byte
- 例外:GSM默認采用7bit編碼
GB2312編碼 GBK編碼 GB18030編碼 XXXX編碼
- 如果全世界都用英語那ASCII碼也夠用了
- 但中國 日本 韓國 也想用計算機顯示自己國家的文字
- 所以中國制定了GB2312 日文制定了Shift_JIS 韓文制定了EUC_KR
- 每個國家都制定了自己的編碼 一般都用2~4字節來表示一個文字
Unicode字符集
- 每個國家的編碼不一樣導致很容易產生亂碼
- 如何讓所以國家都用一個表來確定字符的編號(學名為碼位 / 碼點 / Code Point)
- Unicode就孕育出生了(統一碼、萬國碼、單一碼)
- Unicode准備了1114112個編號來存放世界上所有的文字
- 1114112 二進制為 10001 00000000 00000000 20bit
- 2020年3月10日發布了最新的Unicode®13.0.0.pdf
UTF-32 (或 UCS-4)編碼
- 規定每個字符都以4byte(32bit)去存儲 讀取 傳輸
- 優點
- 快速獲取字符數量
- 快速獲取數據中的指定字符
- 缺點
- 本來1byte(4bit)就能保存的數據都需要用4byte(32bit) 來保存很浪費容量
- 存儲 讀取 傳輸慢
UTF-8編碼
-
使用1~4個byte確定一個字符
-
UTF-8編碼划分Unicode字符集為四個區間
十進制 | 二進制 |
---|---|
0-177 | (00000000 00000000 00000000 00000000)-(00000000 00000000 00000000 01111111) |
178-2047 | (00000000 00000000 00000000 11111111)-(00000000 00000000 01111111 11111111) |
2048-65535 | (00000000 00000000 11111111 11111111)-(00000000 01111111 11111111 11111111) |
65536-1114111 | (00000000 11111111 11111111 11111111)-(01111111 11111111 11111111 11111111) |
- 四個區間分別對應四個公式
公式 |
---|
0xxxxxx |
110xxxxx 10xxxxxx |
1110xxxx 10xxxxxx 10xxxxxx |
11110xxx 10xxxxxx 10xxxxxx |
- 例如
字符 | 十進制 | 二進制 | 屬於區間 |
---|---|---|---|
z | 122 | 01111010 | 1 |
鄒 | 37049 | 10010000 10111001 | 3 |
- 字符 'z' 屬於第一區間 套用第一個公式
- 使用 'z' 的二進制 01111010 從右到左依次填入0xxxxxx
- 最終得 'z' 的 UTF-8碼 為 01111010
- 字符 '鄒' 屬於第三區間 套用第三個公式
- 使用 '鄒' 的二進制 10010000 10111001 從右到左依次填入 1110xxxx 10xxxxxx 10xxxxxx
- 最終得 '鄒' 得 UTF-8碼 為 11101001 10000010 10111001
- 優點
- 兼容ASCII碼
- 保存 讀取 傳輸 低於178范圍的字符只需要一個byte(4bit)
- 根據字符的二進制前有多少個1可以確定一個字符的長度
- 缺點
- 不能直接獲取數據包含多少個字符
- 不能直接定位某個字符的二進制位置
總結
- 1個漢字是2個字節 在UTF-8編碼規則下錯誤的
- 以上都是個人見解
- 如有錯漏之處敬請指正
Github:https://github.com/QiangZou