推 goodga: DevOps一樣也是兩顆27”? 08/26 16:49
→ Falldog: Yes 有需求的話,申請三個螢幕應該都不是問題 XD 08/26 16:55
推 goodga: 喔喔 因為我看裡面是寫RD福利,可是DevOps好像又不算是RD 08/26 17:04
→ Lordaeron: 這家就是術文章中UNICODE都搞錯的。 08/26 20:00
→ Falldog: 還請樓上指正有問題的地方 我再修正 thanks 08/26 21:38
→ Lordaeron: unicode只定義code,不定義編碼,utf-OOXX哪堆叫編碼。 08/26 21:52
→ Falldog: 是的 Unicode只定義"Code Point" 不是編碼 文章寫"編號" 08/26 22:09
→ Falldog: 造成你的誤解嗎? 08/26 22:09
→ Lordaeron: 文章是你的,請自理吧!python 的str.... 08/26 22:37
→ Lordaeron: 另一個有趣的是: Foreign Key的故事。真的是夠菜才會 08/26 22:40
→ Lordaeron: 用,優點是還有研究精神。 08/26 22:41
→ Lordaeron: java,c#,python的string 預設為utf-16, 佔2 or 4 bytes 08/27 14:50
→ Lordaeron: 它們都有自己的編碼轉換表,但不是所有的編碼都有。 08/27 14:52
→ Lordaeron: 最後,UTF-32 直接等於unicode 的code point。 08/27 14:53
Java / C# 我不太熟悉,不確定是不是 UTF-16
這邊針對Python的部分回應一下,有錯再幫忙指正
Python 每一個 unicode 儲存在 PY_UNICODE 的 array 裡,其實就是 platform
depending 的 wchar_t[1][2],根據不同的 wchar_t 長度,CPython 會選擇
用 UCS2 or UCS4 進行轉換[3],而UCS2與UTF-16並不盡相同[4]
[1] https://docs.python.org/3/c-api/unicode.html#c.Py_UNICODE
Py_UNICODE
This is a typedef of wchar_t, which is a 16-bit type or 32-bit type depending
on the platform.
[2] CPython Source Code - https://tinyurl.com/44p9xzvd
#define PY_UNICODE_TYPE wchar_t
[3] CPython Source Code - https://tinyurl.com/2dnzsw4t
此 function 將 utf-8 encoding 的 char 轉換成 unicode
int _Py_DecodeUTF8Ex(const char *s, ...){
....
Py_UCS4 ch;
#if SIZEOF_WCHAR_T == 4
ch = ucs4lib_utf8_decode(&s, e, (Py_UCS4 *)unicode, &outpos);
#else
ch = ucs2lib_utf8_decode(&s, e, (Py_UCS2 *)unicode, &outpos);
#endif
[4] WIKI UTF-16與UCS-2的關係 https://tinyurl.com/hkubh5kn
UTF-16可看成是UCS-2的父集。
※ 編輯: Falldog (118.160.212.186 臺灣), 08/27/2021 19:48:55
→ Lordaeron: 如果一下UTF-16,一下UTF-32,哪要自行轉碼就中招了。 08/27 22:49
→ Lordaeron: 這種跨平台方式,太奇怪了。 08/27 22:49
→ Lordaeron: UTF-16是包括SURROGATE 的部分, UCS-2 沒有。 08/27 22:54
→ Lordaeron: UCS-4=UTF-32。 08/27 22:54
→ Lordaeron: Python 3預設為UTF-8 了。 08/27 22:56
我不確定你要說的是?
原本是大大說我們的Unicode的技術文錯了,想了解是錯在哪邊,現在比較像在討論
Unicode 的其他定義了? 那趁這個機會小小分享一下我所知道的內容
Python是跨平台語言,直譯器是用C語言寫的,直譯器又稱CPython,所以討論Python的
一些行為時,都可以看CPython的source code來觀察Python的行為
CPython在compile時就決定了它的Unicode是哪個版本了,所以在下載安裝Python時,是
會區分是Windows/Linux/macOS 32/64bit,舊版的似乎還會分unicode/ansi版? 所以,
上面說的CPython會根據wchar_t的長度來決定使用UCS2 or UCS4來轉換Unicode,是在
compile time時就決定了,所以並不是run time時一下UTF-16 一下UTF-32
Python3的source code encoding預設是UTF-8[1],並不是Python3 Unicode預設是UTF-8。
Python3 預設的 str 是 unicode,而 unicode 是以 UCS2 or UCS4 來處理的話,就看
你的平台來決定(wchar_t的長度不一樣)
Unicode 真的是滿複雜的,各平台作法有差異,UTF-16因為byte數不足,而搞了個
surrogate的作法出來。也趁大大的疑問我再複習了一下,我也是現在才知道
UCS4 == UTF-32
[1] https://docs.python.org/3/howto/unicode.html#the-string-type
The default encoding for Python source code is UTF-8
※ 編輯: Falldog (118.160.212.186 臺灣), 08/27/2021 23:24:49
→ Hsins: CPython 指的是直譯器,不是 source code 吧 08/28 00:11
感謝提醒,已修正
※ 編輯: Falldog (118.166.55.15 臺灣), 08/28/2021 06:59:24
→ Lordaeron: 沒有unicode的string, 只有unicode編碼的string. 08/28 08:35
→ Lordaeron: Python3 的string是什麼,我在win上測,CODE 如下: 08/28 10:17
→ Lordaeron: s='中文'\n es=s.encode()\n b=bytearray(es)\n 08/28 10:18
→ Lordaeron: print(b)得到 bytearray(b'\xe4\xb8\xad\xe6\x96\x87') 08/28 10:19
→ Lordaeron: 最後,都民國幾年了,還UCS-2哪麼surrogate全死。 08/28 10:20
原來 L大 指的是 string.encode() 這個 function 預設值已經改成 utf-8 了是嗎?
那沒錯,Python3後改的,因為我在探討的大部分是 CPython 在 "Unicode(wchar_t)" 的
情況下怎麼處理(儲存)的
另外,文章中我本來也沒有對UCS2 UCS4做太多的著墨,因為我並沒有深入研究,所以前
面回應UCS2與UTF-16的部分應該有誤,因為討論的文件不太多,我看source code可能理
解的不夠完全[1]
以下是 CPython 的 unicodeobject.c 裡面處理 utf-8 decode 的邏輯
int _Py_DecodeUTF8Ex(
....
while (s < e) {
Py_UCS4 ch;
#if SIZEOF_WCHAR_T == 4
ch = ucs4lib_utf8_decode(&s, e, (Py_UCS4 *)unicode, &outpos);
#else
ch = ucs2lib_utf8_decode(&s, e, (Py_UCS2 *)unicode, &outpos);
#endif
if (ch > 0xFF) {
#if SIZEOF_WCHAR_T == 4
Py_UNREACHABLE();
#else
assert(ch > 0xFFFF && ch <= MAX_UNICODE);
/* write a surrogate pair */
unicode[outpos++] = (wchar_t)Py_UNICODE_HIGH_SURROGATE(ch);
unicode[outpos++] = (wchar_t)Py_UNICODE_LOW_SURROGATE(ch);
再回過頭來看這個_Py_DecodeUTF8Ex的function,CPython在coding上,都是使用UCS的
keywoard來宣告2 byte or 4 bytes的word長度,而在wchar_t == 4的情況下是使用UCS4
的"編碼"方式儲存進wchar_t的陣列內容,而在wchar_t == 2的情況下,CPython自行處
理了 surrogate 的部分,所以可以理解成CPython在wchar_t == 2的環境下是使用UTF-16
的"編碼"方式,將Unicode的內容儲存入wchar_t的陣列裡
[1] CPython Source Code - https://tinyurl.com/2dnzsw4t
推 Hsins: 我看了一下那篇技術文章,對照前面 L 大提出的那句 08/28 10:56
→ Hsins: 「unicode只定義code,不定義編碼」 08/28 10:57
→ Hsins: 應該想要表示的是即使都是使用 unicode 也需要指定編碼方式 08/28 11:00
→ Hsins: 除非是 ASCII 中的那些才能保證解碼跟編碼一致 08/28 11:01
→ Hsins: 原本文中這句「例如 硬 的 Code Point 為 U+786C」不甚精確 08/28 11:02
→ Hsins: ,因為在 unicode 字符集下面,指定不同的編碼方式所對應出 08/28 11:03
→ Hsins: 編號與符號之間的關係,並不是一定的 08/28 11:03
→ Hsins: 這樣說也有點不太準確…應該說 unicode 決定了字元的二進制 08/28 11:16
→ Hsins: 位值,但沒有確切規定怎麼進行編碼和儲存 08/28 11:17
→ Lordaeron: 哇!!非常好的解釋。 08/28 11:55
我也同意 L大提的 「unicode只定義code,不定義編碼」這句話是正確的
所以,技術文提到的 「Unicode 的定義,對每個「字」都有一個獨一無二的編號」如果
還是造成誤解成編碼的感覺,那就是我用字的問題了 Orz
如果說,H大說,技術文中提到的「例如 硬 的 Code Point 為 U+786C」這句話不夠精
確的話,我只能提出更多說明,佐證我們的看法是不是一樣的了(因為我們都同意
unicode只定義code,不定義編碼)
根據 Python Document 對 Unicode 的說明如下[1]
The Unicode standard describes how characters are represented by code points.
A code point value is an integer in the range 0 to 0x10FFFF (about 1.1
million values, the actual number assigned is less than that). In the
standard and in this document, a code point is written using the notation
U+265E to mean the character with value 0x265e (9,822 in decimal).
以"硬"這個字來說,在Unicode裡面它有個獨一無二的"編號" (Code Point),可以表示
成U+786C,所以,在大部分的Unicode的工具網站,它的編號也會是U+786C [2]。而這個
Code Point,在不同的編碼(UTF-8, UTF-16-LE, UTF-16-BE, UTF-32-LE, UTF-32-BE,
Big5, ....),就會以不一樣的內容與順序儲存入binary/memeory/storage裡面
https://imgur.com/a/3CMdz9J
所以,呼應你的話,Unicode定義了每個字的Code Point,至於怎麼轉換成binary儲存起
來,就是各個"編碼"(encoding)在做的事情了。如果因為其中一句話,讓你們覺得整篇
技術文都廢言的話,那我的確應該再修飾一下幾個關鍵句子 ^^"
其實文章中比較想深入探討的是Python3的unicode str的概念,對一般的使用者來說,
其實都是封裝起來的概念,對應到CPython的source code裡,到底是用什麼型式(編碼)
儲存進storage/binary/memory裡面,所以才帶到wchar_t,與不同平台之間的差異
怎麼徵才文變技術文了... Orz
[1] https://docs.python.org/3/howto/unicode.html
[2] https://unicode-table.com/en/786C/
※ 編輯: Falldog (118.166.55.15 臺灣), 08/28/2021 17:06:08
→ Hsins: 沒有呀,我覺得那篇技術文沒錯呀… 08/28 17:11
→ Lordaeron: wchar_t只是2 BYTE 或 4 BYTE 的問題而已。你要存什麼 08/28 19:32
→ Lordaeron: 並不是重點,如果你沒有碼表的話。 08/28 19:33
→ Lordaeron: 說到最後,你們不強調"高手",相信沒興趣拆你台。 08/28 19:33
→ Lordaeron: Big5和Unicode 無關。別扯在一起。 08/28 19:36
→ Lordaeron: 看SOURCE沒什麼,別再PO 了。UNICODE的事相信很多前輩 08/28 19:45
→ Lordaeron: 都有寫了,你就好好的徵才(沒多久前才徵過一樣的) 08/28 19:46
→ Lordaeron: 但真的不用強調什麼技術公司。that's all,好好的做生 08/28 19:47
→ Lordaeron: 意,顧好員工就好。技術,再磨吧。 08/28 19:47
推 answerseeker: 推一下這個領域耕耘的新創 08/29 19:50
→ gn01838335: 結論是沒有字碼表xd不要寫程式嗎 08/31 21:18
→ gn01838335: Xdd 08/31 21:18
→ gn01838335: 我這些過王安碼轉檔路過,轉碼文字最精準是先是拆字 08/31 21:25
→ gn01838335: 碼並來源文字byte 編對應的字碼。若你轉碼系統沒有這 08/31 21:25
→ gn01838335: 個對應檔一天就出現亂碼。回到源頭解byte組文字,做 08/31 21:25
→ gn01838335: 字典檔才能避免文字出錯。尤其是一堆中文造字程式出 08/31 21:25
→ gn01838335: 來的鬼東西 08/31 21:25
→ gn01838335: 這篇勾起我對中文字痛恨的回憶…天天在轉碼 08/31 21:28
→ gn01838335: 要保證轉碼出錯就是規定要走什麼編碼。但如果輸入資 08/31 21:32
→ gn01838335: 料本來就沒有在編碼裡面,例如windows壓縮就是很好的 08/31 21:32
→ gn01838335: 例子。oS預設(假設中文)的語言如果用沒有在裡面的 08/31 21:32
→ gn01838335: 字碼(簡體字)會直接報錯誤。通常大型系統都會嚴格 08/31 21:32
→ gn01838335: 定義使用字碼和轉型,很少通吃。 08/31 21:32
※ 編輯: Falldog (114.24.3.196 臺灣), 09/16/2021 21:38:41