碎碎念: 這幾天在學習Python對Unicode的支持python
上學的時候,計算機基礎課上總能聽到老師講什麼字節,字符,Unicode,UTF-8吧啦吧啦一堆,反正我是隻記住了名字,至於具體這些名字所表達的含義,當時的我是一點也沒有想要好好了解的意願,必竟是一看就會睡着的內容。數據庫
那時候內心想的是,老師能不能快點講一些能夠「實戰」的東西,這些理論的內容真真太無聊,太無趣了。app
啊啊啊,但是,出來混,果然早晚是要還的,那時候沒聽的講,如今都要本身補回來,QAQ...學習
這篇文章主要是模擬Unicode轉換UTF8編碼的過程,以此來加深對Unicode和UTF8之間關係的理解。測試
首先明確4個基礎概念:編碼
字節: 1字節由8個二進制位組成,是計算機計算存儲容量的一個計量單位(1 Byte=8 bit)code
字符: 1個符號,由1個或多個字節組成orm
Unicode(簡稱UCS ): 編碼規則,爲每種語言中的每一個字符設定了統一而且惟一的二進制編碼。unicode
能夠將Unicode理解成一個字符數據庫,每一個字符都與惟一的數字關聯,稱爲code point。這樣,英文大寫字母A的codepoint是U+0041。而歐元符號的codepoint是U+20A0,其餘相似。一個文本字符串就是這樣一系列的codepoint,表示字符串中每一個字符元素。字符串
UTF-8(Transfer format): Unicode編碼規則的具體實現(將code point轉換到程序數據的編碼方案)
我是這樣理解的:字節:單位名稱,字符:內容呈現,Unicode:制定規則,UTF-8:規則實現
UTF-8最大的一個特色,就是它是一種變長的編碼方式。它可使用1~4個字節表示一個符號,根據不一樣的符號而變化字節長度。
UTF-8的編碼規則很簡單,只有二條:
Unicode符號範圍(16進制) | UTF-8編碼方式(2進制) |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
下面,以漢字「嚴」爲例,演示如何實現UTF-8編碼 已知「嚴」的unicode是4E25(100111000100101),根據上表,能夠發現4E25處在第三行的範圍內(0000 0800-0000 FFFF),所以「嚴」的UTF-8編碼須要三個字節,即格式是「1110xxxx 10xxxxxx 10xxxxxx」。
而後,從「嚴」的最後一個二進制位開始,依次從後向前填入格式中的x,多出的位補0。這樣就獲得了,「嚴」的UTF-8編碼是「11100100 10111000 10100101」,轉換成十六進制就是E4B8A5。
腳本主要實現思路
代碼:
UnicodeSet={"A":"41","嚴":"4E25","漢":"6C49","test":"10ffff"} utf8Set=[] test = "嚴" if test in UnicodeSet: # 將code point 轉換爲10進制數字 tencode = int(UnicodeSet[test], base=16) twocode = bin(tencode)[2:] #判斷測試字符須要幾個字節表示 if 0<= tencode <=127: codeLevel=1 elif 128 <= tencode <= 2047: codeLevel = 2 elif 2048 <= tencode <= 65535: codeLevel = 3 elif 65536 <= tencode <=1114111: codeLevel = 4 else: print("超出編碼範圍") # 按UTF8編碼規則對code point 進行編碼 if codeLevel == 1: rescode = twocode else: pre = -6 after = len(twocode) for i in range(codeLevel): singleByte = "10"+twocode[pre:after] pre = pre - 6 after = after -6 if i == codeLevel-1: numzero = 8-codeLevel-len(twocode[0:-after])-1 singleByte ="1"*codeLevel+"0"+"0"*numzero+twocode[0:-after] utf8Set.append(singleByte) utf8code = "".join(utf8Set[::-1]) rescode = hex(int(utf8code,base=2))[2:] print(f"Unicode定義字符 {test} 的 codepoint爲: {UnicodeSet[test]}\ \n 將codepoint轉換爲utf8編碼:{rescode}")
小白的記錄帖,不足之處,歡迎指出~
歡迎轉載,轉載請註明出處~