1. 程式人生 > >UTF-8、UTF-16、UTF-32編碼的相互轉換

UTF-8、UTF-16、UTF-32編碼的相互轉換

相關文章

最近在考慮寫一個可以跨平臺的通用字串類,首先需要搞定的就是編碼轉換問題。

vs預設儲存程式碼檔案,使用的是本地code(中文即GBK,日文即Shift-JIS),也可以使用帶BOM的UTF-8。
gcc則是UTF-8,有無BOM均可(原始碼的字符集可以由引數-finput-charset指定)。
那麼原始碼可以採用帶BOM的UTF-8來儲存。而windows下的unicode是UTF-16編碼;linux則使用UTF-8或UTF-32。因此不論在哪種系統裡,程式在處理字串時都需要考慮UTF編碼之間的相互轉換。

下面直接貼出演算法程式碼。演算法上我借鑑了秦建輝(

http://blog.csdn.net/jhqin)的UnicodeConverter,只是在外面增加了一些泛型處理,讓使用相對簡單。

  1. namespace transform  
  2. {  
  3.     /* 
  4.         UTF-32 to UTF-8 
  5.     */
  6.     inlinestaticsize_t utf(uint32 src, uint8* des)  
  7.     {  
  8.         if (src == 0) return 0;  
  9.         staticconst byte PREFIX[] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };  
  10.         staticconst uint32 CODE_UP[] =  
  11.         {  
  12.             0x80,           // U+00000000 - U+0000007F
  13.             0x800,          // U+00000080 - U+000007FF
  14.             0x10000,        // U+00000800 - U+0000FFFF
  15.             0x200000,       // U+00010000 - U+001FFFFF
  16.             0x4000000,      // U+00200000 - U+03FFFFFF
  17.             0x80000000      // U+04000000 - U+7FFFFFFF
  18.         };  
  19.         size_t i, len = sizeof(CODE_UP) / sizeof(uint32);  
  20.         for(i = 0; i < len; ++i)  
  21.             if (src < CODE_UP[i]) break;  
  22.         if (i == len) return 0; // the src is invalid
  23.         len = i + 1;  
  24.         if (des)  
  25.         {  
  26.             for(; i > 0; --i)  
  27.             {  
  28.                 des[i] = static_cast<uint8>((src & 0x3F) | 0x80);  
  29.                 src >>= 6;  
  30.             }  
  31.             des[0] = static_cast<uint8>(src | PREFIX[len - 1]);  
  32.         }  
  33.         return len;  
  34.     }  
  35.     /* 
  36.         UTF-8 to UTF-32 
  37.     */
  38.     inlinestaticsize_t utf(const uint8* src, uint32& des)  
  39.     {  
  40.         if (!src || (*src) == 0) return 0;  
  41.         uint8 b = *(src++);  
  42.         if (b < 0x80)  
  43.         {  
  44.             des = b;  
  45.             return 1;  
  46.         }  
  47.         if (b < 0xC0 || b > 0xFD) return 0; // the src is invalid
  48.         size_t len;  
  49.         if (b < 0xE0)  
  50.         {  
  51.             des = b & 0x1F;  
  52.             len = 2;  
  53.         }  
  54.         else
  55.         if (b < 0xF0)  
  56.         {  
  57.             des = b & 0x0F;  
  58.             len = 3;  
  59.         }  
  60.         else
  61.         if (b < 0xF8)  
  62.         {  
  63.             des = b & 0x07;  
  64.             len = 4;  
  65.         }  
  66.         else
  67.         if (b < 0xFC)  
  68.         {  
  69.             des = b & 0x03;  
  70.             len = 5;  
  71.         }  
  72.         else
  73.         {  
  74.             des = b & 0x01;  
  75.             len = 6;  
  76.         }  
  77.         size_t i = 1;  
  78.         for (; i < len; ++i)  
  79.         {  
  80.             b = *(src++);  
  81.             if (b < 0x80 || b > 0xBF) return 0; // the src is invalid
  82.             des = (des << 6) + (b & 0x3F);  
  83.         }  
  84.         return len;  
  85.     }  
  86.     /* 
  87.         UTF-32 to UTF-16 
  88.     */
  89.     inlinestaticsize_t utf(uint32 src, uint16* des)  
  90.     {  
  91.         if (src == 0) return 0;  
  92.         if (src <= 0xFFFF)  
  93.         {  
  94.             if (des) (*des) = static_cast<uint16>(src);  
  95.             return 1;  
  96.         }  
  97.         else
  98.         if (src <= 0xEFFFF)  
  99.         {  
  100.             if (des)  
  101.             {  
  102.                 des[0] = static_cast<uint16>(0xD800 + (src >> 10) - 0x40);  // high
  103. 相關推薦

    如何使GCC支援中文(utf-8)的變數名函式名?

    知乎原文地址 作者:@狗屎咖啡 目前VS 和Clang都是支援utf-8的變數名、函式名,但 GCC不支援。 有人提意見,提了好幾年了:UTF-8 support for identifier names in GCC GCC並沒有解決,但官方給了一個解決方案:FAQ - GCC

    【轉載】關於Python腳本開頭兩行的:#!/usr/bin/python和# -*- coding: utf-8 -*-的作用 – 指定文件編碼類型

    ron 標識 精確 log 解析器 開始 html weight .org 下面的內容來自:http://www.cnblogs.com/blueskylcc/p/5332642.html, 對方也是轉的,不過沒有找到轉載的出處; 1、#!/usr/bin/python

    TensorFlow學習筆記(UTF-8 問題解決 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte)

    show 學習 github red star ims fas can pri 我使用VS2013 Python3.5 TensorFlow 1.3 的開發環境 UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte

    響應報文utf-8為什麼設定了charset=utf-8,還編碼錯誤?

    響應報文utf-8為什麼設定了charset=utf-8,還編碼錯誤? Content-Type:text/html;charset=utf-8/r/n這裡要注意格式 習慣了等號前後加空格,這可能會導致使用utf-8編碼時出現錯誤,如果使用utf-8編碼出現錯誤時 一定

    UTF-8 ASCII GBK GB2312 GB18030等字元編碼的關係

    準備寫一個 JNI HelloWorld: public class HelloWorld { public native void displayHelloWorld();//所有native關鍵詞修飾的都是對本地的宣告 static { System.lo

    PHP實現Unicode和Utf-8編碼相互轉換

    Unicode和Utf-8編碼的區別 Unicode是一個字符集,定義了字元與數字之間的對應關係,在Unicode中:漢字“字”對應的數字是23383(十進位制),十六進位制表示為5B57。在Unicode中,我們有很多方式將數字23383表示成程式中的資料,包括:UT

    utf-8轉gb2312,gb2312轉utf-8

    這兩種程式碼格式之間的轉換網上有很多的文章,都寫的很詳細, 但是從網上找相關的工具,發現不是很好用,舉個例子,沒有辦法選擇檔案與檔案格式,依稀記得之前做過這樣一個東西,想起來用一下, 找了半天找到了一個14年寫的小軟體,開啟介面一年發現當時寫的好奇葩, 對於utf-8轉

    深度學習——卷積神經網絡 的經典網絡(LeNet-5AlexNetZFNetVGG-16GoogLeNetResNet)

    足夠 論文 ogl 相關性 spa 原因 線性 pad fan 一、CNN卷積神經網絡的經典網絡綜述 下面圖片參照博客:http://blog.csdn.net/cyh_24/article/details/51440344 二、LeNet-5網絡

    深度學習——卷積神經網路 的經典網路(LeNet-5AlexNetZFNetVGG-16GoogLeNetResNet)

    一、CNN卷積神經網路的經典網路綜述二、LeNet-5網路輸入尺寸:32*32卷積層:2個降取樣層(池化層):2個全連線層:2個輸出層:1個。10個類別(數字0-9的概率)   LeNet-5網路是針對灰度圖進行訓練的,輸入影象大小為32*32*1,不包含輸入層的情況下共有7

    二進制八進制十進制十六進制之間的相互轉換

    函數 pri 數據 數據類型 相互轉換 轉換 結果 之間 int 二進制、八進制、十進制、十六進制之間的相互轉換。 代碼: # -*- coding: UTF-8 -*- # 主要的思想,就是,先把數字轉成10進制,利用10進制中的自帶函數去解決 # 十進制數字 num

    FastJson對於JSON格式字串JSON物件及JavaBean之間的相互轉換

    一、FastJson簡介 FastJson對於json格式字串的解析主要用到了一下三個類:         JSON:fastJson的解析器,用於JSON格式字串與JSON物件及javaBean之間的轉換。         JSONObject:fastJson提

    SpringCloud工作筆記047---FastJson對於JSON格式字串JSON物件及JavaBean之間的相互轉換

    fastJson對於json格式字串的解析主要用到了一下三個類: JSON:fastJson的解析器,用於JSON格式字串與JSON物件及javaBean之間的轉換。 JSONObject:fastJson提供的json物件。 JSONArray:fastJson提

    MFC中CString類字串與長整型浮點型字元陣列char資料之間的相互轉換

    一、長整型資料與CString類字串相互轉換 1.將長整型資料轉換為CString字串類 CString str; long ld; str.Format(_T("%ld"),ld); 2.將CString字串類轉換為長整型資料 CString str; long ld; ld=

    時間戳(timestamp)時間字串(datetimestr)時間(datetime)之間的相互轉換

    總覽 # 時間戳轉時間字串(timestamp to datetimeStr) def timestampToDateStr(stamps, frmt='%Y-%m-%d %H:%M:%S'): #

    Java程式設計:10進位制數62進位制數進行相互轉換

    場景:要求隨機生成長度較短的使用者名稱,保證使用者名稱唯一,同時保證使用者名稱不易被推測出。 解決思路:按序生成唯一序列號,通過演算法將序列號進行混淆,之後將其轉化為 62 進位制的 11 位字串。通

    森林與二叉樹的相互轉換

    eight inf http 轉換 alt 森林 技術分享 分享 相互 樹、森林與二叉樹的相互轉換

    fastjson json字串和JavaBeanListMap及複雜集合型別的相互轉換

    本文主要示例兩部分內容: JavaBean、List、Map、複雜集合 轉換成 json字串; json字串 轉換成 JavaBean、List、Map、複雜集合; 定義POJO: public class A { private Str

    單色點陣圖顏色(色彩)點陣圖相互轉換

    SetBkColor The SetBkColor function sets the current background color to the specified color value, or to the nearest physical color if the device cannot re

    c++中stringconst char*和char*之間的相互轉換

    1. string轉const char* string s = “abc”; const char* c_s = s.c_str(); 2. const char* 轉string,直接賦值即可 const char* c_s = “abc”; string s(c_s

    15關於String,File,InputStream之間的相互轉換

    1、介紹了關於String,File,InputStream之間的相互轉換       1.1  String2InputStream /** * String2InputStr