熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

Unicode編碼 解釋UCS、UTF、BMP、BOM

2013-11-23 19:23:34  來源: Java核心技術 

  這是一篇程序員寫給程序員的趣味讀物所謂趣味是指可以比較輕松地了解一些原來不清楚的概念增進知識類似於打RPG游戲的升級整理這篇文章的動機是兩個問題
  
  問題一
  
  使用Windows記事本的另存為可以在GBKUnicodeUnicode big endian和UTF這幾種編碼方式間相互轉換同樣是txt文件Windows是怎樣識別編碼方式的呢?
  
  我很早前就發現UnicodeUnicode big endian和UTF編碼的txt文件的開頭會多出幾個字節分別是FFFE(Unicode)FEFF(Unicode big endian)EFBBBF(UTF但這些標記是基於什麼標准呢?
  
  問題二
  
  最近在網上看到一個ConvertUTFc實現了UTFUTF和UTF這三種編碼方式的相互轉換對於Unicode(UCS)GBKUTF這些編碼方式我原來就了解但這個程序讓我有些糊塗想不起來UTF和UCS有什麼關系
  
  查了查相關資料總算將這些問題弄清楚了順帶也了解了一些Unicode的細節寫成一篇文章送給有過類似疑問的朋友本文在寫作時盡量做到通俗易懂但要求讀者知道什麼是字節什麼是十六進制
  
  big endian和little endian
  
  big endian和little endian是CPU處理多字節數的不同方式例如字的Unicode編碼是C那麼寫到文件裡時究竟是將C寫在前面還是將寫在前面?如果將C寫在前面就是big endian如果將寫在前面就是little endian
  
  endian這個詞出自《格列佛游記》小人國的內戰就源於吃雞蛋時是究竟從大頭(BigEndian)敲開還是從小頭(LittleEndian)敲開由此曾發生過六次叛亂一個皇帝送了命另一個丟了王位
  
  我們一般將endian翻譯成字節序將big endian和little endian稱作大尾小尾
  
  字符編碼內碼順帶介紹漢字編碼
  
  字符必須編碼後才能被計算機處理計算機使用的缺省編碼方式就是計算機的內碼早期的計算機使用位的ASCII編碼為了處理漢字程序員設計了用於簡體中文的GB和用於繁體中文的big
  
  GB(年)一共收錄了個字符包括個漢字和個其它符號漢字區的內碼范圍高字節從BF低字節從AFE占用的碼位是*=其中有個空位是DFADFE
  
  GB支持的漢字太少年的漢字擴展規范GBK收錄了個符號它分為漢字區和圖形符號區漢字區包括個字符
  
  從ASCIIGB到GBK這些編碼方法是向下兼容的即同一個字符在這些方案中總是有相同的編碼後面的標准支持更多的字符在這些編碼中英文和中文可以統一地處理區分中文編碼的方法是高字節的最高位不為按照程序員的稱呼GBGBK都屬於雙字節字符集 (DBCS)
  
  年的GB是取代GBK的正式國家標准該標准收錄了個漢字同時還收錄了藏文蒙文維吾爾文等主要的少數民族文字從漢字字匯上說GB在GB個漢字的基礎上增加了CJK擴展A的個漢字(Unicode碼xxdb一共收錄了個漢字
  
  CJK就是中日韓的意思Unicode為了節省碼位將中日韓三國語言中的文字統一編碼GB就是ISO/IEC 的中文版相當於Unicode
  
  GB的編碼采用單字節雙字節和字節方案其中單字節雙字節和GBK是完全兼容的字節編碼的碼位就是收錄了CJK擴展A的個漢字 例如UCS的x在GB中的編碼應該是EFUCS的x在GB中的編碼應該是EF
  
  微軟提供了GB的升級包但這個升級包只是提供了一套支持CJK擴展A的個漢字的新字體新宋體並不改變內碼Windows 的內碼仍然是GBK
  
  這裡還有一些細節
  
  GB的原文還是區位碼從區位碼到內碼需要在高字節和低字節上分別加上A
  
  對於任何字符編碼編碼單元的順序是由編碼方案指定的與endian無關例如GBK的編碼單元是字節用兩個字節表示一個漢字 這兩個字節的順序是固定的不受CPU字節序的影響UTF的編碼單元是word(雙字節)word之間的順序是編碼方案指定的word內部的字節排列才會受到endian的影響後面還會介紹UTF
  
  GB的兩個字節的最高位都是但符合這個條件的碼位只有*=所以GBK和GB的低字節最高位都可能不是不過這不影響DBCS字符流的解析在讀取DBCS字符流時只要遇到高位為的字節就可以將下兩個字節作為一個雙字節編碼而不用管低字節的高位是什麼
  
  UnicodeUCS和UTF
  
  前面提到從ASCIIGBGBK到GB的編碼方法是向下兼容的而Unicode只與ASCII兼容(更准確地說是與ISO兼容)與GB碼不兼容例如字的Unicode編碼是C而GB碼是BABA
  
  Unicode也是一種字符編碼方法不過它是由國際組織設計可以容納全世界所有語言文字的編碼方案Unicode的學名是Universal MultipleOctet Coded Character Set簡稱為UCSUCS可以看作是Unicode Character Set的縮寫
  
  根據維基百科全書()的記載歷史上存在兩個試圖獨立設計Unicode的組織即國際標准化組織(ISO)和一個軟件制造商的協會()ISO開發了ISO 項目Unicode協會開發了Unicode項目
  
  在年前後雙方都認識到世界不需要兩個不兼容的字符集於是它們開始合並雙方的工作成果並為創立一個單一編碼表而協同工作從Unicode開始Unicode項目采用了與ISO 相同的字庫和字碼
  
  目前兩個項目仍都存在並獨立地公布各自的標准Unicode協會現在的最新版本是年的Unicode ISO的最新標准是ISO :
  
  UCS只是規定如何編碼並沒有規定如何傳輸保存這個編碼例如字的UCS編碼是C我可以用個ascii數字來傳輸保存這個編碼也可以用utf編碼:個連續的字節E B 來表示它關鍵在於通信雙方都要認可UTFUTFUTF都是被廣泛接受的方案UTF的一個特別的好處是它與ISO完全兼容UTF是UCS Transformation Format的縮寫
  
  IETF的RFC和RFC以RFC的一貫風格清晰明快又不失嚴謹地描述了UTF和UTF的編碼方法我總是記不得IETF是Internet Engineering Task Force的縮寫但IETF負責維護的RFC是Internet上一切規范的基礎
  
  內碼和code page
  
  目前Windows的內核已經支持Unicode字符集這樣在內核上可以支持全世界所有的語言文字但是由於現有的大量程序和文檔都采用了某種特定語言的編碼例如GBKWindows不可能不支持現有的編碼而全部改用Unicode
  
  Windows使用代碼頁(code page)來適應各個國家和地區code page可以被理解為前面提到的內碼GBK對應的code page是CP
  
  微軟也為GB定義了code pageCP但是由於GB有一部分字節編碼而Windows的代碼頁只支持單字節和雙字節編碼所以這個code page是無法真正使用的
  
  UCSUCSBMP
  
  UCS有兩種格式UCS和UCS顧名思義UCS就是用兩個字節編碼UCS就是用個字節(實際上只用了最高位必須為)編碼下面讓我們做一些簡單的數學游戲
  
  UCS^=個碼位UCS^=個碼位
  
  UCS根據最高位為的最高字節分成^=個group每個group再根據次高字節分為個plane每個plane根據第個字節分為行 (rows)每行包含個cells當然同一行的cells只是最後一個字節不同其余都相同
  
  group 的plane 被稱作Basic Multilingual Plane 即BMP或者說UCS高兩個字節為的碼位被稱作BMP
  
  將UCS的BMP去掉前面的兩個零字節就得到了UCS在UCS的兩個字節前加上兩個零字節就得到了UCS的BMP而目前的UCS規范中還沒有任何字符被分配在BMP之外
  
  UTF編碼
  
  UTF就是以位為單元對UCS進行編碼從UCS到UTF的編碼方式如下
  
  UCS編碼(進制)  UTF 字節流(二進制)
  
   F  xxxxxxx
  
   FF  xxxxx xxxxxx
  
   FFFF  xxxx xxxxxx xxxxxx
  
  例如字的Unicode編碼是CCFFFF之間所以肯定要用字節模板了xxxx xxxxxx xxxxxxC寫成二進制是 用這個比特流依次代替模板中的x得到 即E B
  
  讀者可以用記事本測試一下我們的編碼是否正確需要注意UltraEdit在打開utf編碼的文本文件時會自動轉換為UTF可能產生混淆你可以在設置中關掉這個選項更好的工具是Hex Workshop
  
  UTF位為單元對UCS進行編碼對於小於x的UCS碼UTF編碼就等於UCS碼對應的位無符號整數對於不小於x的UCS碼定義了一個算法不過由於實際使用的UCS或者UCS的BMP必然小於x所以就目前而言可以認為UTF和UCS基本相同但UCS只是一個編碼方案UTF卻要用於實際的傳輸所以就不得不考慮字節序的問題
  
  UTF的字節序和BOM
  
  UTF以字
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26766.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.