我有 3 個位元組表示以 utf8 編碼的 unicode char。例如,我有E2 82 AC(UTF8) 代表 unicode char € (U 20AC)。他們有任何演算法來進行這種轉換嗎?我知道他們是 windows api MultiByteToWideChar 但我想知道他們是否是 E2 82 AC 和 U 20AC 之間的簡單數學關系。utf8 -> utf16 之間的映射也是一個簡單的數學函式,或者它是一個硬編碼的映射。
uj5u.com熱心網友回復:
只需一點數學知識,就可以將有效的UTF-8 位元組序列直接轉換為 UTF-16。
驗證 UTF-8 位元組序列很簡單:只需檢查第一個位元組是否與以下模式之一匹配,并且(byte and $C0) = $80對于序列中的每個后續位元組都是如此。
UTF-8 序列中的第一個位元組告訴您序列中有多少位元組:
(byte1 and $80) = $00: 1 byte
(byte1 and $E0) = $C0: 2 bytes
(byte1 and $F0) = $E0: 3 bytes
(byte1 and $F8) = $F0: 4 bytes
anything else: error
有非常簡單的公式可以將 UTF-8 1 位元組、2 位元組和 3 位元組序列轉換為 UTF-16,因為它們都表示下面的 Unicode 代碼點U 10000,因此可以在 UTF-16 中按原樣表示一個 16 位代碼單元,不需要代理,只是一些小玩意,例如:
1 個位元組:
UTF16 = UInt16(byte1 and $7F)
2個位元組:
UTF16 = (UInt16(byte1 and $1F) shl 6)
or UInt16(byte2 and $3F)
3 個位元組:
UTF16 = (UInt16(byte1 and $0F) shl 12)
or (UInt16(byte2 and $3F) shl 6)
or UInt16(byte3 and $3F)
另一方面,將 UTF-8 4 位元組序列轉換為 UTF-16 稍微復雜一些,因為它代表一個U 10000更高或更高的 Unicode 代碼點,因此需要使用 UTF-16 代理,這需要一些額外的數學計算,例如:
4位元組:
CP = (UInt32(byte1 and $07) shl 18)
or (UInt32(byte2 and $3F) shl 12)
or (UInt32(byte3 and $3F) shl 6)
or UInt32(byte4 and $3F)
CP = CP - $10000
highSurrogate = $D800 UInt16((CP shr 10) and $3FF)
lowSurrogate = $DC00 UInt16(CP and $3FF)
UTF16 = highSurrogate, lowSurrogate
現在,話雖如此,讓我們看一下您的示例:E2 82 AC
第一個位元組是($E2 and $F0) = $E0,第二個位元組是($82 and $C0) = $80,第三個位元組是($AC and $C0) = $80,所以這確實是一個有效的 UTF-8 3 位元組序列。
將這些位元組值代入 3 位元組公式,您將得到:
UTF16 = (UInt16($E2 and $0F) shl 12)
or (UInt16($82 and $3F) shl 6)
or UInt16($AC and $3F)
= (UInt16($02) shl 12)
or (UInt16($02) shl 6)
or UInt16($2C)
= $2000
or $80
or $2C
= $20AC
事實上,Unicode 代碼點U 20AC以 UTF-16 編碼為$20AC.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/509897.html
