⑴ 我怎樣才能在全局忽略UTF-8字元串無效的位元組序列
如果你只是想在原始位元組進行操作,你可以試試它的編碼為ASCII-8BIT /二進制。
str.force_encoding("BINARY").split("n")
這不會讓你的U回來,不過,因為在這種情況下,源字元串為ISO-8859(或喜歡):
"- Men\xFC -".force_encoding("ISO-8859-1").encode("UTF-8")
=> "- Menü -"
如果你想獲得multibyte字元,你必須知道的源字元集是什麼。
一旦你force_encoding如果數據是從您的資料庫,你可以改變你的ASCII-8BIT或二進制編碼;ruby應該舉報他們據此即可。或者,您可以monkeypatch資料庫驅動程序來強制編碼的讀取它的所有字元串。這是一個巨大的,雖然,可能是完全錯誤的做法。
正確的答案將是解決你的字元串編碼。這可能需要它們的資料庫修復,資料庫驅動程序連接的編碼修復,或combinations。所有的位元組仍然存在,但如果你正在處理一個給定的字元集,你應該,如果可能的話,讓ruby知道,你希望你的數據在該編碼。錯誤是mysql2驅動程序連接到已在拉丁文編碼數據的MySQL資料庫,但要指定UTF-8字元集進行連接。該導軌從DB取拉丁文的數據並把它解釋為UTF-8,而不是將其解釋為拉丁文,然後可以轉換為UTF-8。
如果你能在這里闡述的字元串中,答案是可能的。您也可以看看這個答案的可能的全局(-ish)Rails的解決方案,默認字元串編碼。
⑵ java 如何判斷一個字元串中有並找到4位元組的字元。
int indexOf(String str)返回指定字元在此字元串中第一次出現的位置.
如果不是你要的答案,建議去看看JDK中的Sting類方面的東西。
⑶ 位元組寫入流中字元串類型為什麼去掉高八位
數據包是自定義的,如果數據包包含包頭,標志位,校驗和什麼的,在顯示或保存數據的時候都需要去掉,如果不包含的話就不用去掉高八位了,看實際情況而定
⑷ 如何處理emoji等4位元組的Unicode字元
1.
Unicode是什麼
Unicode(中文:萬國碼、國際碼、統一碼、單一碼)是計算機科學領域里的一項業界標准。它對世界上大部分的文字系統進行了整理、編碼,使得電腦可以用更為簡單的方式來呈現和處理文字。
簡單說來,就是把世界上所有語言的字,加上所有能找到的符號(如高音譜號、麻將、emoji)用同一套編碼表示出來。
2.
UTF-8是什麼
UTF-8(8-bit Unicode Transformation
Format)是一種針對Unicode的可變長度字元編碼。可變長度的意思在於,如果能使用1位元組編碼,UTF-8絕對不會使用2位元組去表示。舉個例子,UTF-8的1位元組部分和ASCII碼是相同的。所以表示'A'這個字元的時候,UTF-8與ASCII碼不僅編碼相同,而且都是只使用1位元組。
3.
Character Set和Collation是什麼
Character
Set是一套符號以及編碼。Collation是character set的排序方法。在中文版的MySQL中,character
set被翻譯為「字元集」,collation被翻譯為「整理」。
舉個例子,UTF-8是character
set,utf8_unicode_ci和utf8mb4_unicode_ci就是collation。
Collation的作用主要有二:字元排序與查找字元。
字元排序的作用是顯而易見的,不過還是要用幾個例子加以說明。比如要比較a和b的大小,因為在26個英文字母裡面,a在b前,所以在編碼的時候,也把a放在b前面。這樣就產生了第一種排序方式,通過字元編碼的大小來排序。而在中文裡面,「年」和「日」的排序,除了按照字元編碼大小,還可以有另外一些標准。比如可以按照筆畫序,「年」的第一筆是丿,「日」的第一筆是丨,而丨是排在丿前的,所以就將「日」排在前面;也可以按拼音序,「年」是n開頭,「日」是r開頭,於是把「年」排在前面。除此以外,還可以定義部首序、筆畫數序等等,而不同的排序方法會有不同的結果。英文也有大小寫敏感與不敏感的排序方式。種種不同的排序方式,就形成了不同的collations。
Collation的第二個作用則是查找字元是否在一個字元集裡面。既然是一個有序的集合,則可以快速地通過一個編碼值確定一個字元是否在集合內。這個特性是我們在不知不覺中使用的。比如使用中文輸入法,就是通過輸入法找到一個編碼,通過collation把它查找出來的。
4.
Unicode再深入:Plane和中日韓越統一表意文字
utf8_unicode_ci和utf8mb4_unicode_ci這兩個collations都是基於UTF-8編碼的,但排序方面或多或少會有差別。可是更大的差別是它查找字元的集合。這需要提到一個Unicode的概念:Plane。
4.1.
Plane
Plane中文譯作「Unicode平面字元映射」,不過我們還是叫它plane好啦。目前的Unicode字元分為17個planes,而每個plane擁有65536(即2^16)個代碼點。可以認為一個plane就是一個范圍的編碼。
Plane
0也叫做BMP(Basic Multilingual Plane,基本多文種平面),存放著世界上各種語言與標記中最常用的字元。
Plane
1也叫做SMP(Supplementary Multilingual
Plane,多文種補充平面),放著表情符號(emoji)、字母與數學符號、音樂符號、太玄經(太極符號)、裝飾符號、撲克牌、麻將符號、箭頭擴展和一些世界上各種語言不太常用的文字等等。
Plane 2也叫做SIP(Supplementary Ideographic
Plane,表意文字補充平面),用於存放統一漢字(見4.2)的一些罕用字與漢藏語系其他語言的用字(如粵語用字)。
4.2.
統一漢字的分布
對於統一漢字(中日韓越統一表意文字,CJKV Unified
Ideographs)來說,BMP存放著最初的版本(也是最常用字)與擴展A區的漢字。擴展B區到即將到來的擴展E區都放在SIP中。
在這些區中,除了獨立字源的字,還有同一個字源或部首不同的變體或寫法。比如「戶」的第一筆,中國大陸與香港寫作「戶」,台灣寫作「戶」,日本則寫作「戸」。這些差異也會在Unicode中用三個不同的編碼去表示。所以B區到E區有不少此種字體。
舉些B區的例子。網路上之前流行的「不會功夫不要艹我」被寫成「「xx巭嫑莪」,其中「xx」這個字就是在B區。而粵語「x雞」(閹雞)、「x完松」(和一個人發生關系後棄之而去)兩個詞的首字也是在B區。
5.
utf8_unicode_ci和utf8mb4_unicode_ci的異同
這兩種collations所對應的字元都是UTF-8編碼的一個子集。utf8_unicode_ci最多能找到3個位元組的Unicode編碼,而utf8mb4_unicode_ci則能找到4個位元組的編碼。由於調整後的UTF-8編碼格式規定最多使用4位元組(原來是6位元組)編碼,所以utf8mb4系列可以說是覆蓋了整個Unicode編碼。
由於utf8_unicode_ci最多能找到3個位元組的編碼,意味著它只支持BMP中的字元,對於SMP與SIP以及其他頭一位元組不為0x00、需要4位元組編碼的planes來說,utf8_unicode_ci這種collation是無法支持。當使用4位元組的字元(如emoji與B區以後的統一漢字)對使用此種collation的欄位進行增刪查改時,資料庫會報一個非法字元的異常。而utf8mb4則沒有此問題。由此也看出,utf8mb4_unicode_ci是utf8_unicode_ci的超集。
6.
utf8mb4_unicode_ci的優缺點
utf8mb4系列的Collation在MySQL
5.5以上開始支持。相比起utf8_unicode_ci,它有如下的特性:
1)
在數據表中,對於BMP中的字元(最多使用3位元組的字元,最常用的字元),兩種collations具有完全相同的存儲特性:相同的碼值,相同的編碼方式,相同的存儲長度。不會增加任何的存儲開銷。
2)
在數據表中,對於其他plains的字元,utf8系列的collation根本不能存儲,而utf8mb4系列的collations則可以存儲。
3)
在數據表中,對於變長的欄位(如VARCHAR2,TEXT),utf8mb4最大可存儲的字元可能少於utf8系列的collation。
4)
在索引中,對於文本類型的欄位,utf8mb4可索引的字元少於utf8系列的collations。如InnoDB的索引最多使用767位元組。如果使用utf8mb4,每一個字元都會預留4位元組做索引,而utf8則預留3位元組。故此前者是191個字元,後者是255個字元。
5)
由於4)的原因,加上字元集大,utf8mb4的性能可能比utf8系列的collations低。
6)
若升級前的欄位做了索引,需要把索引字元限制在191字元或以內。
7. 當前系統用哪個好
在當前的系統,全部都使用utf8_unicode_ci這種collation。但是在存儲網頁標題時,標題帶有SMP或者SIP的字元,如emoji、粵語字,會引發資料庫寫入異常。於是,就有兩種解決方向:
1)
扔掉。
1.1) 扔掉或截斷引發異常的字。採取此種方法,需要對每一個標題進行掃描。
1.2)
扔掉整條記錄。可以採取掃描法,或者扔掉引發異常的記錄。
2) 升級到utf8mb4。會略為降低資料庫性能。
7.1.
性能考慮
首先對於寫入性能,查找字體的性能損耗由於在寫入前字元都已經變成編碼,基本可以忽略。對於網路傳輸的性能,則需要繼續查找相關資料繼續查證。但初步估計由於目前資料庫在本地,故此這部分開銷的增長不太明顯。
而對於索引的性能,由於網頁標題這一欄位沒有做索引,在可預見的將來也未有此計劃,故此沒有性能的損耗,也沒有升級兼容性的擔心。
況且,倘若走扔掉數據的方向,若採取掃描法,則需要付出掃描的開銷。若採取扔掉記錄法,則會先觸發事務回滾,其他記錄需要下次重新寫入。而且當一批記錄寫入時有k個記錄引發異常,則需要回滾與重試k次,除非使用掃描法預先掃描出這些異常的記錄。但這也會引入額外的程序與資料庫開銷。若不使用事務,則資料庫總體寫入性能會大為降低。
雖然沒有實測過,但從感覺上來定性判斷,似乎扔掉記錄比升級collation帶來的性能退化要大。
7.2.
存儲空間考慮
當前的網頁標題是使用VARCHAR2存儲。對於現在可用的、常見的BMP字元,不會引入額外的存儲開銷。BMP字元在VARCHAR的類型下不會為每一字元引入額外33%的空間開銷。反之,定長的CHAR就會引入這種額外開銷。
7.3.
目標數據考慮
網頁標題作為以後特徵分析的數據源。在分析需求完全沒有確定的情況下,我認為扔掉任何數據都是不宜採取的辦法,特別是整條記錄扔掉更是不推薦。因為現階段我們沒有一套標准去判定何為有效數據、何為無效數據。有可能引發異常的那部分數據確實是沒用的數據,也有可能那部分人群更傾向於在我們平台上活躍使用。既然各種可能性都存在,我們主動放棄一部分可能性,似乎不太恰當。
7.4.
API設計與兼容性考慮
由於utf8_unicode_ci與utf8mb4_unicode_ci都是使用UTF-8編碼,所以對於JAVA,使用MyBatis生成的代碼是一樣的,都是使用String類型。這點已經實測過。加上這兩種collations在BMP中的編碼完全一致,所以使用3位元組與4位元組的系統,對於BMP中的字元都是完全兼容、正常顯示的。而對於3位元組的系統,4位元組的字元一般會顯示成一個方框,或者在一個方框中有幾個小數字,不會引發系統異常。
8.
總結
誠然,emoji對分詞分析目前來說還沒有什麼效果,粵語詞而且在SIP中也只是其中一部分,也不知道有多少日本動漫或者愛情動作片的網頁會遇到這些生僻字,音樂符號也少人用,太極符號也不是每次都出現,一些數學增補的字元與箭頭增補圖案也不是每個人都會用。這些加起來可能不知夠不夠全部的千分之一。
但是倘若每一兩個小時就會由於字元不能寫入,引發資料庫的異常。通過上面的分析,我認為增加這種兼容性帶來的成本是可以接受的。
故此,我建議使用升級的方法,兼容所有Unicode字元。
轉載
⑸ 如何將4位元組utf-8的emoji表情轉換為unicode字元編碼
1. Unicode是什麼
Unicode(中文:萬國碼、國際碼、統一碼、單一碼)是計算機科學領域里的一項業界標准。它對世界上大部分的文字系統進行了整理、編碼,使得電腦可以用更為簡單的方式來呈現和處理文字。
簡單說來,就是把世界上所有語言的字,加上所有能找到的符號(如高音譜號、麻將、emoji)用同一套編碼表示出來。
2. UTF-8是什麼
UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字元編碼。可變長度的意思在於,如果能使用1位元組編碼,UTF-8絕對不會使用2位元組去表示。舉個例子,UTF-8的1位元組部分和ASCII碼是相同的。所以表示'A'這個字元的時候,UTF-8與ASCII碼不僅編碼相同,而且都是只使用1位元組。
3. Character Set和Collation是什麼
Character Set是一套符號以及編碼。Collation是character set的排序方法。在中文版的MySQL中,character set被翻譯為「字元集」,collation被翻譯為「整理」。
舉個例子,UTF-8是character set,utf8_unicode_ci和utf8mb4_unicode_ci就是collation。
Collation的作用主要有二:字元排序與查找字元。
字元排序的作用是顯而易見的,不過還是要用幾個例子加以說明。比如要比較a和b的大小,因為在26個英文字母裡面,a在b前,所以在編碼的時候,也把a放在b前面。這樣就產生了第一種排序方式,通過字元編碼的大小來排序。而在中文裡面,「年」和「日」的排序,除了按照字元編碼大小,還可以有另外一些標准。比如可以按照筆畫序,「年」的第一筆是丿,「日」的第一筆是丨,而丨是排在丿前的,所以就將「日」排在前面;也可以按拼音序,「年」是n開頭,「日」是r開頭,於是把「年」排在前面。除此以外,還可以定義部首序、筆畫數序等等,而不同的排序方法會有不同的結果。英文也有大小寫敏感與不敏感的排序方式。種種不同的排序方式,就形成了不同的collations。
Collation的第二個作用則是查找字元是否在一個字元集裡面。既然是一個有序的集合,則可以快速地通過一個編碼值確定一個字元是否在集合內。這個特性是我們在不知不覺中使用的。比如使用中文輸入法,就是通過輸入法找到一個編碼,通過collation把它查找出來的。
4. Unicode再深入:Plane和中日韓越統一表意文字
utf8_unicode_ci和utf8mb4_unicode_ci這兩個collations都是基於UTF-8編碼的,但排序方面或多或少會有差別。可是更大的差別是它查找字元的集合。這需要提到一個Unicode的概念:Plane。
4.1. Plane
Plane中文譯作「Unicode平面字元映射」,不過我們還是叫它plane好啦。目前的Unicode字元分為17個planes,而每個plane擁有65536(即2^16)個代碼點。可以認為一個plane就是一個范圍的編碼。
Plane 0也叫做BMP(Basic Multilingual Plane,基本多文種平面),存放著世界上各種語言與標記中最常用的字元。
Plane 1也叫做SMP(Supplementary Multilingual Plane,多文種補充平面),放著表情符號(emoji)、字母與數學符號、音樂符號、太玄經(太極符號)、裝飾符號、撲克牌、麻將符號、箭頭擴展和一些世界上各種語言不太常用的文字等等。
Plane 2也叫做SIP(Supplementary Ideographic Plane,表意文字補充平面),用於存放統一漢字(見4.2)的一些罕用字與漢藏語系其他語言的用字(如粵語用字)。
4.2. 統一漢字的分布
對於統一漢字(中日韓越統一表意文字,CJKV Unified Ideographs)來說,BMP存放著最初的版本(也是最常用字)與擴展A區的漢字。擴展B區到即將到來的擴展E區都放在SIP中。
在這些區中,除了獨立字源的字,還有同一個字源或部首不同的變體或寫法。比如「戶」的第一筆,中國大陸與香港寫作「戶」,台灣寫作「戶」,日本則寫作「戸」。這些差異也會在Unicode中用三個不同的編碼去表示。所以B區到E區有不少此種字體。
舉些B區的例子。網路上之前流行的「不會功夫不要艹我」被寫成「「xx巭嫑莪」,其中「xx」這個字就是在B區。而粵語「x雞」(閹雞)、「x完松」(和一個人發生關系後棄之而去)兩個詞的首字也是在B區。
5. utf8_unicode_ci和utf8mb4_unicode_ci的異同
這兩種collations所對應的字元都是UTF-8編碼的一個子集。utf8_unicode_ci最多能找到3個位元組的Unicode編碼,而utf8mb4_unicode_ci則能找到4個位元組的編碼。由於調整後的UTF-8編碼格式規定最多使用4位元組(原來是6位元組)編碼,所以utf8mb4系列可以說是覆蓋了整個Unicode編碼。
由於utf8_unicode_ci最多能找到3個位元組的編碼,意味著它只支持BMP中的字元,對於SMP與SIP以及其他頭一位元組不為0x00、需要4位元組編碼的planes來說,utf8_unicode_ci這種collation是無法支持。當使用4位元組的字元(如emoji與B區以後的統一漢字)對使用此種collation的欄位進行增刪查改時,資料庫會報一個非法字元的異常。而utf8mb4則沒有此問題。由此也看出,utf8mb4_unicode_ci是utf8_unicode_ci的超集。
6. utf8mb4_unicode_ci的優缺點
utf8mb4系列的Collation在MySQL 5.5以上開始支持。相比起utf8_unicode_ci,它有如下的特性:
1) 在數據表中,對於BMP中的字元(最多使用3位元組的字元,最常用的字元),兩種collations具有完全相同的存儲特性:相同的碼值,相同的編碼方式,相同的存儲長度。不會增加任何的存儲開銷。
2) 在數據表中,對於其他plains的字元,utf8系列的collation根本不能存儲,而utf8mb4系列的collations則可以存儲。
3) 在數據表中,對於變長的欄位(如VARCHAR2,TEXT),utf8mb4最大可存儲的字元可能少於utf8系列的collation。
4) 在索引中,對於文本類型的欄位,utf8mb4可索引的字元少於utf8系列的collations。如InnoDB的索引最多使用767位元組。如果使用utf8mb4,每一個字元都會預留4位元組做索引,而utf8則預留3位元組。故此前者是191個字元,後者是255個字元。
5) 由於4)的原因,加上字元集大,utf8mb4的性能可能比utf8系列的collations低。
6) 若升級前的欄位做了索引,需要把索引字元限制在191字元或以內。
7. 當前系統用哪個好
在當前的系統,全部都使用utf8_unicode_ci這種collation。但是在存儲網頁標題時,標題帶有SMP或者SIP的字元,如emoji、粵語字,會引發資料庫寫入異常。於是,就有兩種解決方向:
1) 扔掉。
1.1) 扔掉或截斷引發異常的字。採取此種方法,需要對每一個標題進行掃描。
1.2) 扔掉整條記錄。可以採取掃描法,或者扔掉引發異常的記錄。
2) 升級到utf8mb4。會略為降低資料庫性能。
7.1. 性能考慮
首先對於寫入性能,查找字體的性能損耗由於在寫入前字元都已經變成編碼,基本可以忽略。對於網路傳輸的性能,則需要繼續查找相關資料繼續查證。但初步估計由於目前資料庫在本地,故此這部分開銷的增長不太明顯。
而對於索引的性能,由於網頁標題這一欄位沒有做索引,在可預見的將來也未有此計劃,故此沒有性能的損耗,也沒有升級兼容性的擔心。
況且,倘若走扔掉數據的方向,若採取掃描法,則需要付出掃描的開銷。若採取扔掉記錄法,則會先觸發事務回滾,其他記錄需要下次重新寫入。而且當一批記錄寫入時有k個記錄引發異常,則需要回滾與重試k次,除非使用掃描法預先掃描出這些異常的記錄。但這也會引入額外的程序與資料庫開銷。若不使用事務,則資料庫總體寫入性能會大為降低。
雖然沒有實測過,但從感覺上來定性判斷,似乎扔掉記錄比升級collation帶來的性能退化要大。
7.2. 存儲空間考慮
當前的網頁標題是使用VARCHAR2存儲。對於現在可用的、常見的BMP字元,不會引入額外的存儲開銷。BMP字元在VARCHAR的類型下不會為每一字元引入額外33%的空間開銷。反之,定長的CHAR就會引入這種額外開銷。
7.3. 目標數據考慮
網頁標題作為以後特徵分析的數據源。在分析需求完全沒有確定的情況下,我認為扔掉任何數據都是不宜採取的辦法,特別是整條記錄扔掉更是不推薦。因為現階段我們沒有一套標准去判定何為有效數據、何為無效數據。有可能引發異常的那部分數據確實是沒用的數據,也有可能那部分人群更傾向於在我們平台上活躍使用。既然各種可能性都存在,我們主動放棄一部分可能性,似乎不太恰當。
7.4. API設計與兼容性考慮
由於utf8_unicode_ci與utf8mb4_unicode_ci都是使用UTF-8編碼,所以對於JAVA,使用MyBatis生成的代碼是一樣的,都是使用String類型。這點已經實測過。加上這兩種collations在BMP中的編碼完全一致,所以使用3位元組與4位元組的系統,對於BMP中的字元都是完全兼容、正常顯示的。而對於3位元組的系統,4位元組的字元一般會顯示成一個方框,或者在一個方框中有幾個小數字,不會引發系統異常。
8. 總結
誠然,emoji對分詞分析目前來說還沒有什麼效果,粵語詞而且在SIP中也只是其中一部分,也不知道有多少日本動漫或者愛情動作片的網頁會遇到這些生僻字,音樂符號也少人用,太極符號也不是每次都出現,一些數學增補的字元與箭頭增補圖案也不是每個人都會用。這些加起來可能不知夠不夠全部的千分之一。
但是倘若每一兩個小時就會由於字元不能寫入,引發資料庫的異常。通過上面的分析,我認為增加這種兼容性帶來的成本是可以接受的。
故此,我建議使用升級的方法,兼容所有Unicode字元。
⑹ 如何去掉文本非法utf8字元串
在BB10 Cascades開發環境中可以輕松地通過JsonDataAccess類讀寫json文件,將json文件中的數據轉換成內存對象。
不過對內於中國開發者來講有容個苦惱,就是通過樣例讀取json文件時如果json文件中有中文字元,所有中文字元在BB10 Cascades組件中顯示時會顯示為亂碼,就是顯示成一個方框。
解決這個問題的方法很簡單,就是設置json文件的編碼格式,因為BB10 Cascades開發環境使用UTF-8作為預設編碼,所以需要將程序使用的Json文件轉成UTF-8格式。
當然,對json文件的編碼轉換可以使用很多種方式,如使用UltraEdit等工具,不過最方便的是使用BB10 Cascades自帶的工具進行轉換。
在BB10 Cascades開發環境中右鍵選擇需要處理的json文件,點擊「Properties」打開文件屬性框,然後在「Text file encording」選擇項中選擇「Other」,然後選擇「UTF-8」。這樣就可以將你需要處理的json文件轉換成UTF-8格式,在程序中使用時就不會有亂碼了。
⑺ utf8 中 有佔4位元組的中文字元嗎
下面的內容轉自我的網路空間,是我收集來的,在這里看起來如果覺得排版不好,可以直接看我的空間內的文章:http://hi..com/newkedison/blog/item/1c7d2c392cc192f63b87ce12.html
有關UTF-8的一些資料2008年06月13日 星期五 08:17一, 最重要的,UTF-8和Unicode的轉換
UTF-8 編碼是一種被廣泛應用的編碼,這種編碼致力於把全球的語言納入一個統一的編碼,目前已經將幾種亞洲語言納入。UTF 代表 UCS Transformation Format.
UTF-8 採用變長度位元組來表示字元,理論上最多可以到 6 個位元組長度。UTF-8 編碼兼容了 ASC II(0-127), 也就是說 UTF-8 對於 ASC II 字元的編碼是和 ASC II 一樣的。對於超過一個位元組長度的字元,才用以下編碼規范:
左邊第一個位元組1的個數表示這個字元編碼位元組的位數,例如兩位位元組字元編碼樣式為為:110xxxxx 10xxxxxx; 三位位元組字元的編碼樣式為:1110xxxx 10xxxxxx 10xxxxxx.;以此類推,六位位元組字元的編碼樣式為:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx。 xxx 的值由字元編碼的二進製表示的位填入。只用最短的那個足夠表達一個字元編碼的多位元組串。例如:
Unicode 字元: 00 A9(版權符號) = 1010 1001, UTF-8 編碼為:11000010 10101001 = 0x C2 0xA9; 字元 22 60 (不等於符號) = 0010 0010 0110 0000, UTF-8 編碼為:11100010 10001001 10100000 = 0xE2 0x89 0xA0
以上轉換例子已經確認是正確的,不用懷疑,如果看不懂請再仔細想想
Unicode編碼和utf-8編碼之間的對應關系表
The table below summarizes the format of these different octet types.
The letter x indicates bits available for encoding bits of the
character number.
Char. number range | UTF-8 octet sequence
(hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx //////A/////////
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
這是一個Unicode編碼和utf-8編碼之間的對應關系表。中文的Unicode編碼范圍在0000 0800-0000 FFFF 中。
二, 關於BOM
UTF-8以位元組為編碼單元,沒有位元組序的問題。UTF-16以兩個位元組為編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每個編碼單元的位元組序。例如收到一個「奎」的Unicode編碼是594E,「乙」的Unicode編碼是4E59。如果我們收到UTF-16位元組流「594E」,那麼這是「奎」還是「乙」?
Unicode規范中推薦的標記位元組順序的方法是BOM。BOM不是「Bill Of Material」的BOM表,而是Byte Order Mark。BOM是一個有點小聰明的想法:
在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字元,它的編碼是FEFF。而FFFE在UCS中是不存在的字元,所以不應該出現在實際傳輸中。UCS規范建議我們在傳輸位元組流前,先傳輸字元"ZERO WIDTH NO-BREAK SPACE"。
這樣如果接收者收到FEFF,就表明這個位元組流是Big-Endian的;如果收到FFFE,就表明這個位元組流是Little-Endian的。因此字元"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。
UTF-8不需要BOM來表明位元組順序,但可以用BOM來表明編碼方式。字元"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗證一下)。所以如果接收者收到以EF BB BF開頭的位元組流,就知道這是UTF-8編碼了。
三, VB實現UTF-8轉Unicode的函數
1.不使用API
Function Utf8ToUnicode(ByRef Utf() As Byte) As String
Dim utfLen As Long
utfLen = -1
On Error Resume Next
utfLen = UBound(Utf)
If utfLen = -1 Then Exit Function
On Error GoTo 0
Dim i As Long, j As Long, k As Long, N As Long
Dim B As Byte, cnt As Byte
Dim Buf() As String
ReDim Buf(utfLen)
i = 0
j = 0
Do While i <= utfLen
B = Utf(i)
If (B And &HFC) = &HFC Then
cnt = 6
ElseIf (B And &HF8) = &HF8 Then
cnt = 5
ElseIf (B And &HF0) = &HF0 Then
cnt = 4
ElseIf (B And &HE0) = &HE0 Then
cnt = 3
ElseIf (B And &HC0) = &HC0 Then
cnt = 2
Else
cnt = 1
End If
If i + cnt - 1 > utfLen Then
Buf(j) = "?"
Exit Do
End If
Select Case cnt
Case 2
N = B And &H1F
Case 3
N = B And &HF
Case 4
N = B And &H7
Case 5
N = B And &H3
Case 6
N = B And &H1
Case Else
Buf(j) = Chr(B)
GoTo Continued:
End Select
For k = 1 To cnt - 1
B = Utf(i + k)
N = N * &H40 + (B And &H3F)
Next
Buf(j) = ChrW(N)
Continued:
i = i + cnt
j = j + 1
Loop
Utf8ToUnicode = Join(Buf, "")
End Function
2. 使用API (包括Unicode轉UTF-8)
Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByRef lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar As String, ByVal lpUsedDefaultChar As Long) As Long
Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Const CP_UTF8 = 65001
Function Utf8ToUnicode(ByRef Utf() As Byte) As String
Dim lRet As Long
Dim lLength As Long
Dim lBufferSize As Long
lLength = UBound(Utf) - LBound(Utf) + 1
If lLength <= 0 Then Exit Function
lBufferSize = lLength * 2
Utf8ToUnicode = String$(lBufferSize, Chr(0))
lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(Utf(0)), lLength, StrPtr(Utf8ToUnicode), lBufferSize)
If lRet <> 0 Then
Utf8ToUnicode = Left(Utf8ToUnicode, lRet)
End If
End Function
Function UnicodeToUtf8(ByVal UCS As String) As Byte()
Dim lLength As Long
Dim lBufferSize As Long
Dim lResult As Long
Dim abUTF8() As Byte
lLength = Len(UCS)
If lLength = 0 Then Exit Function
lBufferSize = lLength * 3 + 1
ReDim abUTF8(lBufferSize - 1)
lResult = WideCharToMultiByte(CP_UTF8, 0, StrPtr(UCS), lLength, abUTF8(0), lBufferSize, vbNullString, 0)
If lResult <> 0 Then
lResult = lResult - 1
ReDim Preserve abUTF8(lResult)
UnicodeToUtf8 = abUTF8
End If
End Function
Private Sub Command1_Click()
Dim byt() As Byte
byt = UnicodeToUtf8("測試")
Debug.Print Hex(byt(0)) & Hex(byt(1)) & Hex(byt(2))
Debug.Print Utf8ToUnicode(byt())
End Sub
參考資料:http://hi..com/newkedison/blog/item/1c7d2c392cc192f63b87ce12.html
⑻ 如何判斷一個字元串是否是UTF8編碼
UTF8是以8bits即1Bytes為編碼的最基本單位,當然也可以有基於16bits和32bits的形式,分別稱為UTF16和UTF32,但目前用得不多,而UTF8則被廣泛應用在文件儲存和網路傳輸中。
編碼原理
先看這個模板:
UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx
編碼步驟:
1) 首先確定需要多少個8bits(octets)
2) 按照上述模板填充每個octets的高位bits
3) 把字元的bits填充至x中,字元順序:低位→高位,UTF8順序:最後一個octet的最末位x→第一個octet最高位x
根據UTF8編碼,最多可由6個位元組組成,所以UTF8是1-6位元組編碼組成
⑼ 如何識別字元串是否是UTF8編碼的 / 藍訊
UTF8是以8bits即1Bytes為編碼的最基本單位,當然也可以有基於16bits和32bits的形式,分別稱為UTF16和UTF32,但目前用得不多,而UTF8則被廣泛應用在文件儲存和網路傳輸中。
編碼原理
先看這個模板:
UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx
編碼步驟:
1) 首先確定需要多少個8bits(octets)
2) 按照上述模板填充每個octets的高位bits
3) 把字元的bits填充至x中,字元順序:低位→高位,UTF8順序:最後一個octet的最末位x→第一個octet最高位x
根據UTF8編碼,最多可由6個位元組組成,所以UTF8是1-6位元組編碼組成
BOOL IsTextUTF8(char* str,ULONGLONG length)
{
DWORD nBytes=0;//UFT8可用1-6個位元組編碼,ASCII用一個位元組
UCHAR chr;
BOOL bAllAscii=TRUE; //如果全部都是ASCII, 說明不是UTF-8
for(int i=0; i<length; ++i)
{
chr= *(str+i);
if( (chr&0x80) != 0 ) // 判斷是否ASCII編碼,如果不是,說明有可能是UTF-8,ASCII用7位編碼,但用一個位元組存,最高位標記為0,o0xxxxxxx
bAllAscii= FALSE;
if(nBytes==0) //如果不是ASCII碼,應該是多位元組符,計算位元組數
{
if(chr>=0x80)
{
if(chr>=0xFC&&chr<=0xFD)
nBytes=6;
else if(chr>=0xF8)
nBytes=5;
else if(chr>=0xF0)
nBytes=4;
else if(chr>=0xE0)
nBytes=3;
else if(chr>=0xC0)
nBytes=2;
else
return FALSE;
nBytes--;
}
}
else //多位元組符的非首位元組,應為 10xxxxxx
{
if( (chr&0xC0) != 0x80 )
return FALSE;
nBytes--;
}
}
if( nBytes > 0 ) //違返規則
return FALSE;
if( bAllAscii ) //如果全部都是ASCII, 說明不是UTF-8
return FALSE;
return TRUE;
}