本文預設你已經知道 big5 編碼的結構,如果不知道,建議先去了解一下。
理解許功蓋問題後,我們可以得知 big5 用兩組 16 進制的字元編碼表達中文文字,而出問題的部分在第二個字元編碼,如果該字元編碼和 '\' 相同,就容易出事。
反斜槓 '\' 的 16 進制編碼就是 0x5C
,它不是中文字符,所以在 big5 編碼中只用一組 16 進制的字元編碼表示: 5C
。
如果某個字的編碼是以 5C
結尾的,那就會出事,例如許(B35C)、功(A55C)、蓋(BB5C)、么(A45C)......以及一大堆例子。
目標就是把這些 big5 編碼以 5C 結尾的中文字符挑出來。
python 可以使用 str.encode
獲取指定字元的 big5 編碼的 bytes 物件對象。
注意!不是 str 物件,而是 bytes 物件,這個東西是無法直接使用的,裡面就是一大堆數字,請記得這個,待會我們還需要面對它。
可以嘗試 print() 看看它長怎樣,你會得到類似像這樣的東西 b'\xbf\xdf'
,這是輸入「貓」後直接 print 的結果,然後你就會困惑這三小。
順帶一提,輸入許功蓋系列的字,會得到 b'\xb3\\'
,後面理應出現的 5C 被替換成反斜槓了!
如果你看懂它,可能會想嘗試直接解析它,然後寫出類似像這樣的東西
while True: |
對啦,寫出這東西的人就是我
但實際輸出後會發現永遠都是 No ,實際檢查 text_big5[-2]
究竟是什麼玩意兒時,會發現是一個不知道什麼意思的數字,那個數字其實就是 bytes 裡面實際存的東西,裡面是一系列的數字,這東西不是給人類看的,不需要仔細弄懂它沒關係。
至於 print 出來的那個東西是怎麼來的...... 和 __str__
這個魔術方法有關,不懂用法的話可以暫時可以先不理它沒關係。
好在 python 有提供內建的方法幫助我們把它轉換成人類可以讀的形式,這邊可以使用 bytes.hex()
,這東西可以把一個 bytes 物件以 16 進位的形式表達。
例如輸入「貓」,就可以得到 bfdf ,雖然是小寫,但這就是我們要的東西,可以直接在編碼表上找到的、人類能讀的形式。
註: bytes.hex() 回傳的是我們熟悉的 str 物件,你可以放心的直接使用
修改後只需要檢查最後兩個字元的編碼是否為 5c (要小寫),如果是,那就輸出 Yes,反之則輸出 No
...
...
...
跟著上面的做法,然後你就會吃一個 WA(line:64)
您的答案為: Yes 正確答案為: No |
從這我們可以理解,某個不應該被判定為許功蓋字元的字被判定成 Yes 了,但為什麼?
因為只有中文字符的 big5 編碼才是用 2 組 16 進制數字表達 (這就是前面我會特別把中文字符加粗放大的原因)
可以嘗試輸入英文、數字等各種奇怪的符號,可以發現有許多非中文字符都只用一組 16 進制數字表達而已
例如 a (61)、z (7a)、A (41) ...... etc,括號內是 big5 編碼
那有什麼非中文字元的 big5 編碼是 5C 的呢? 答案就是反斜槓 '\'
本人,它不是許功蓋字元,但它的 big5 編碼確實是以 5C 結尾的,所以在檢驗的時候記得要考慮到反斜槓,如果輸入的字元是反斜槓,那就直接輸出 no。
參考答案: github 連結