精华内容
下载资源
问答
  • 1.支持文件读入UTF-16、32文本格式数据,并相互转换 2.支持并将转换完的数据保存到文件
  • UTF8、UTF16、UTF32区别

    千次阅读 2019-04-10 22:19:30
    UTF8、UTF16、UTF32区别

    UTF8、UTF16、UTF32都是unicode字符集的字符编码。

    UTF意思是unicode转换格式(Unicode transform format),出现UTF8、UTF16、UTF32是出于要在内存中存储字符的目的而对unicode字符编号进行编码。

    UTF8、UTF16、UTF32区别:(8、16、32可看做每种字符编码存储所需的最少的比特位数)

    UTF8:存在单字节编码,兼容ASCII;当编码为一个字节,则设最高比特位为0;当编码超过一个字节,则需要几个字节,就在第一个字节从最高位开始令连续的几个比特位为1,之后的字节最高位为10。

    UTF32:用固定长度的字节存储字符编码,不管Unicode字符编号需要几个字节,全部都用4个字节存储,直接存储Unicode编号。无需经过字符编号向字符编码的转换步骤,提高效率,用空间换时间。

    UTF16:使用2或4个字节进行存储。对于Unicode编号范围在0~FFFF之间的字符,统一用两个字节存储,无需字符转换,直接存储Unicode编号。对于Unicode字符编号在10000-10FFFF之间的字符,UTF16用四个字节存储,简单说就是:将Unicode字符编号(3字节)分为两部分,高位部分(Unicode字符编号中占1.5个字节)用一个值介于 D800-DBFF (110110yy yyyyyyyy,y为0/1)之间的双字节存储,低位部分用一个值介于 DC00-DFFF (110111xx xxxxxxxx,x为0/1)的双字节存储。而介于D800-DFFF之间的编码在Unicode中是预留的,不安排字符,如果Unicode中有字符的编号是这之间的值,会引发冲突和歧义,很有可能一个不常见字符(存储为四个字节)最后被读成两个常见字符(存储为两个字节)。

    参考:https://blog.csdn.net/pipi1375/article/details/84784392

    展开全文
  • UTF32 UTF-32 UTF32BE UTF-32BE UTF32LE UTF-32LE UCS2 UCS-2 UCS-2LE UCS-2BE UCS-2-INTERNAL UCS4 UCS-4 UCS-4LE UCS-4BE UCS-4-INTERNAL SDL_iconv.c是一部分。 我做了一些修改以构建没有完整...
  • BOM(Byte Order Mark)在分析unicode之前,先把bom(byte order mark)说一下。...来举个很简单的例子,在windows下新建一个文本文件,并另存为utf8的文件格式: 该文件里面没有任何内容,我们再用Hex

    BOM(Byte Order Mark)

    在分析unicode之前,先把bom(byte order mark)说一下。
    bom是unicode字符顺序的标识符号,一般以魔数(magic code)的形式出现在以Unicode字符编码的文件的开始的头部,作为该文件的编码标识。

    来举个很简单的例子,在windows下新建一个文本文件,并另存为utf8的文件格式:
    这里写图片描述

    该文件里面没有任何内容,我们再用Hex Edit来查看该文件的二进制内容:
    这里写图片描述

    0XEFBBBF就是这个文件的bom, 这也就是标识该文件是以utf8为编码格式的,下面来看看字符编码与其bom的对应关系

    字符编码Bom (十六进制)
    UTF-8EF BB BF
    UTF-16 (BE) 大端FE FF
    UTF-16 (LE) 小端FF FE
    UTF-32 (BE) 大端00 00 FE FF
    UTF-32 (LE) 小端FF FE 00 00
    GB-1803084 31 95 33

    上面只是列举了一些常用的字符编码,上面其它的bom验证也可以像上面的utf8 bom一样验证。

    UTF-8编码剖析

    Unicode编码以code point 来标识每一个字符, code point 的范围是
    0x000000 – 0x10FFFF,也就是每一个字符的code point都落在这个范围,而utf8的一个字符可以用1-4字节来表示,可能有人会说这code point最大也就是0x10FFFF,为什么最大不是可以用三个字节表示呢?那是因为utf8有自己独特的表示格式,先来看看下面的对应关系:

    字节数字符code point位数最小的code point最大的code point第一个字节第二个字节第三个字节第四个字节
    17U+0000U+007F0XXXXXXX
    211U+0080U+07FF110XXXXX10XXXXXX
    316U+0800U+FFFF1110XXXX10XXXXXX10XXXXXX
    421U+10000U+10FFFF11110XXX10XXXXXX10XXXXXX10XXXXXX

    看到上面的对应关系,应该可以看出点规律了吧,总结一下:

    • 当某个字符的code point (cp简称) U+0000 <= cp <= U+007F 落在这个范围内,这时只需要一个字节来表示 0XXXXXXX,将该字符的code point (7位)填入X的位置,就可以得到该字符的utf8的编码后的格式了。我们以小写字母a举个例子,a的code point是01100001, 经过utf8编码后 01100001(0x61), 可以用hex edit验证一下
      这里写图片描述

    再用个稍微大点的code point 来验证下, 中文汉字 code point 为 0x52A0 二进制格式 ‭0101 0010 1010 0000‬, 按照上表中的规则,该字符需要用三个字节来表示,按照填充规则 ,第一个字节 1110XXXX -> 11100101 , 第二个字节10XXXXXX -> 10001010 , 第三个字节10XXXXXX -> 10100000, 组合起来就是11100101 10001010 10100000 ‭HEX-> 0xE58AA0‬, 用hex edit来验证一下
    这里写图片描述
    EF BB BF 是utf8的bom, 结果一致,可以自己试一试。

    UTF-16编码剖析

    utf-16编码的单元是两个字节,也就是16位。utf-16编码格式在程序内存里经常使用,因为它比较高效, java中Character 字符用的就是utf-16编码格式,在早期的时候,世界上所有的字符都可以用两个字节标识,也就是code point范围 U+0000 – U+FFFF,这样utf-16就可以很好的表示了,而且也不用像utf8那样按照固定的模板组合,可以直接用字符的code point表示,非常高效, 但是随着时间的推移,所有字符远远不能用两个字节的code point 表示了,那为了兼容code point 超过U+FFFF的字符 就出现字符代理对(Surrogate pair), utf16就是使用代理对来表示code point 范围在 U+10000 -> U+10FFFF之间的字符,当然也就的使用四个字节来表示该字符了。对于Surrogate pair 与code point 之间的对应关系算法,等会儿再说, 先来看下utf16对于code point 小与U+10000的字符表示,其实用的就是字符的code point表示,这里还区分了大小端的表示法。还是来看中文汉字 code point 为 0x52A0, 推测一下,如果用utf16大端存储,那就是0x52A0;
    如果用utf16小端存储,那就是0xA052, 来用hex edit 验证下。
    utf16 大端
    这里写图片描述
    utf 小端
    这里写图片描述

    结果验证正确。

    对于code point 大于U+FFFF是如何用Surrogate pair 表示的呢?下面来细说。
    来看一个��U+10437 code point 超过U+FFFF的字符。Surrogate pair 分为high surrogate 和low surrogate ,总共四个字节。

    high surrogate 的范围 0xD800 -> 0xDBFF, low surrogate 的范围 0xDC00 -> 0xDFFF

    将code point 转化为surrogate pair 的算法步骤:

    1. 先将字符code point0x10437 减去基数 0x10000, 得到0x437 二进制 ‭0000000001 0000110111‬,这里注意 因为unicode 的最大code point 不超过U+10FFFF, 也就是code point 不会超过20个二进制位, 重点来了
    2. high surrogate 等于上面的结果的前10位 加上最小的high surrogate 0xD800 得到0xD801
    3. low surrogate 等于上面的结果的前10位 加上最小的lowsurrogate 0xDC00 得到0xDC37
    4. 组合起来就是0xD801 DC37 大端
      用hex edit 来验证下
      这里写图片描述

    小端utf16 0x01D8 37DC
    这里写图片描述

    当然将utf16编码后的格式 反过来用code point 表示就是过程的逆向,可以根据 字符是否落在 high surrogate 的范围 0xD800 -> 0xDBFF, low surrogate 的范围 0xDC00 -> 0xDFFF 这个范围来判断该utf16字符是否是surrogate pair。然后再进行转化,这里就不再赘述了。java 中的Character类中这两种过程的都有

        1. surrogate pair 转化为code point
        public static int toCodePoint(char high, char low) {
            // Optimized form of:
            // return ((high - MIN_HIGH_SURROGATE) << 10)
            //         + (low - MIN_LOW_SURROGATE)
            //         + MIN_SUPPLEMENTARY_CODE_POINT;
            return ((high << 10) + low) + (MIN_SUPPLEMENTARY_CODE_POINT
                                           - (MIN_HIGH_SURROGATE << 10)
                                           - MIN_LOW_SURROGATE);
        }
    
        2. code point 转化为 surrogate pair
        public static char highSurrogate(int codePoint) {
            return (char) ((codePoint >>> 10)
                + (MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT >>> 10)));
        }
        public static char lowSurrogate(int codePoint) {
            return (char) ((codePoint & 0x3ff) + MIN_LOW_SURROGATE);
        }

    UTF-32编码剖析

    utf-32用四个字节表示每一个字符,直接用字符的code point表示,非常高效,不需要任何的转化操作,但占用的存储空间却是很大的,会有空间的浪费。

    比如说 小写字母a code point 是0x61 用utf32表示就是大端 -> 0x00 00 00 61 ; 小端 -> 0x61 00 00 00, 这样会造成存储空间的浪费,当然应用场景不同而已,当追求高效的转换而忽略存储空间的浪费这个问题,utf32编码格式是比较好的选择。而utf8的原则是尽可能的节省存储空间,牺牲转化的效率,各有各的好处。

    展开全文
  •  UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {   ConversionResult result = conversionOK;    const  UTF16* source = *sourceStart;   UTF32* target = *...

    首先是最重要的版权信息。

    /*
     * Copyright 2001-2004 Unicode, Inc.
     * 
     * Disclaimer
     * 
     * This source code is provided as is by Unicode, Inc. No claims are
     * made as to fitness for any particular purpose. No warranties of any
     * kind are expressed or implied. The recipient agrees to determine
     * applicability of information provided. If this file has been
     * purchased on magnetic or optical media from Unicode, Inc., the
     * sole remedy for any claim will be exchange of defective media
     * within 90 days of receipt.
     * 
     * Limitations on Rights to Redistribute This Code
     * 
     * Unicode, Inc. hereby grants the right to freely use the information
     * supplied in this file in the creation of products supporting the
     * Unicode Standard, and to make copies of this file in any form
     * for internal or external distribution as long as this notice
     * remains attached.
     */

     

    头文件:

     

    [cpp]  view plain  copy
    1. typedef unsigned int    UTF32;  /* at least 32 bits */  
    2. typedef unsigned short  UTF16;  /* at least 16 bits */  
    3. typedef unsigned char   UTF8;   /* typically 8 bits */  
    4. typedef unsigned char   Boolean; /* 0 or 1 */  
    5.   
    6. /* Some fundamental constants */  
    7. #define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD  
    8. #define UNI_MAX_BMP (UTF32)0x0000FFFF  
    9. #define UNI_MAX_UTF16 (UTF32)0x0010FFFF  
    10. #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF  
    11. #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF  
    12.   
    13. typedef enum {  
    14.     conversionOK,       /* conversion successful */  
    15.     sourceExhausted,    /* partial character in source, but hit end */  
    16.     targetExhausted,    /* insuff. room in target for conversion */  
    17.     sourceIllegal       /* source sequence is illegal/malformed */  
    18. } ConversionResult;  
    19.   
    20. typedef enum {  
    21.     strictConversion = 0,  
    22.     lenientConversion  
    23. } ConversionFlags;  
    24.   
    25. /* This is for C++ and does no harm in C */  
    26. #ifdef __cplusplus  
    27. extern "C" {  
    28. #endif  
    29.   
    30. ConversionResult ConvertUTF8toUTF16 (  
    31.         const UTF8** sourceStart, const UTF8* sourceEnd,   
    32.         UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);  
    33.   
    34. ConversionResult ConvertUTF16toUTF8 (  
    35.         const UTF16** sourceStart, const UTF16* sourceEnd,   
    36.         UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);  
    37.           
    38. ConversionResult ConvertUTF8toUTF32 (  
    39.         const UTF8** sourceStart, const UTF8* sourceEnd,   
    40.         UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);  
    41.   
    42. ConversionResult ConvertUTF32toUTF8 (  
    43.         const UTF32** sourceStart, const UTF32* sourceEnd,   
    44.         UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);  
    45.           
    46. ConversionResult ConvertUTF16toUTF32 (  
    47.         const UTF16** sourceStart, const UTF16* sourceEnd,   
    48.         UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);  
    49.   
    50. ConversionResult ConvertUTF32toUTF16 (  
    51.         const UTF32** sourceStart, const UTF32* sourceEnd,   
    52.         UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);  
    53.   
    54. Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);  
    55.   
    56. #ifdef __cplusplus  
    57. }  
    58. #endif  

     

    实现:

     

    [cpp]  view plain  copy
    1. #include "ConvertUTF.h"  
    2. #ifdef CVTUTF_DEBUG  
    3. #include <stdio.h>  
    4. #endif  
    5.   
    6. static const int halfShift  = 10; /* used for shifting by 10 bits */  
    7.   
    8. static const UTF32 halfBase = 0x0010000UL;  
    9. static const UTF32 halfMask = 0x3FFUL;  
    10.   
    11. #define UNI_SUR_HIGH_START  (UTF32)0xD800  
    12. #define UNI_SUR_HIGH_END    (UTF32)0xDBFF  
    13. #define UNI_SUR_LOW_START   (UTF32)0xDC00  
    14. #define UNI_SUR_LOW_END     (UTF32)0xDFFF  
    15. #define false      0  
    16. #define true        1  
    17.   
    18. /* --------------------------------------------------------------------- */  
    19.   
    20. ConversionResult ConvertUTF32toUTF16 (  
    21.     const UTF32** sourceStart, const UTF32* sourceEnd,   
    22.     UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {  
    23.     ConversionResult result = conversionOK;  
    24.     const UTF32* source = *sourceStart;  
    25.     UTF16* target = *targetStart;  
    26.     while (source < sourceEnd) {  
    27.     UTF32 ch;  
    28.     if (target >= targetEnd) {  
    29.         result = targetExhausted; break;  
    30.     }  
    31.     ch = *source++;  
    32.     if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */  
    33.         /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */  
    34.         if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {  
    35.         if (flags == strictConversion) {  
    36.             --source; /* return to the illegal value itself */  
    37.             result = sourceIllegal;  
    38.             break;  
    39.         } else {  
    40.             *target++ = UNI_REPLACEMENT_CHAR;  
    41.         }  
    42.         } else {  
    43.         *target++ = (UTF16)ch; /* normal case */  
    44.         }  
    45.     } else if (ch > UNI_MAX_LEGAL_UTF32) {  
    46.         if (flags == strictConversion) {  
    47.         result = sourceIllegal;  
    48.         } else {  
    49.         *target++ = UNI_REPLACEMENT_CHAR;  
    50.         }  
    51.     } else {  
    52.         /* target is a character in range 0xFFFF - 0x10FFFF. */  
    53.         if (target + 1 >= targetEnd) {  
    54.         --source; /* Back up source pointer! */  
    55.         result = targetExhausted; break;  
    56.         }  
    57.         ch -= halfBase;  
    58.         *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);  
    59.         *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);  
    60.     }  
    61.     }  
    62.     *sourceStart = source;  
    63.     *targetStart = target;  
    64.     return result;  
    65. }  
    66.   
    67. /* --------------------------------------------------------------------- */  
    68.   
    69. ConversionResult ConvertUTF16toUTF32 (  
    70.     const UTF16** sourceStart, const UTF16* sourceEnd,   
    71.     UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {  
    72.     ConversionResult result = conversionOK;  
    73.     const UTF16* source = *sourceStart;  
    74.     UTF32* target = *targetStart;  
    75.     UTF32 ch, ch2;  
    76.     while (source < sourceEnd) {  
    77.     const UTF16* oldSource = source; /*  In case we have to back up because of target overflow. */  
    78.     ch = *source++;  
    79.     /* If we have a surrogate pair, convert to UTF32 first. */  
    80.     if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {  
    81.         /* If the 16 bits following the high surrogate are in the source buffer... */  
    82.         if (source < sourceEnd) {  
    83.         ch2 = *source;  
    84.         /* If it's a low surrogate, convert to UTF32. */  
    85.         if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {  
    86.             ch = ((ch - UNI_SUR_HIGH_START) << halfShift)  
    87.             + (ch2 - UNI_SUR_LOW_START) + halfBase;  
    88.             ++source;  
    89.         } else if (flags == strictConversion) { /* it's an unpaired high surrogate */  
    90.             --source; /* return to the illegal value itself */  
    91.             result = sourceIllegal;  
    92.             break;  
    93.         }  
    94.         } else { /* We don't have the 16 bits following the high surrogate. */  
    95.         --source; /* return to the high surrogate */  
    96.         result = sourceExhausted;  
    97.         break;  
    98.         }  
    99.     } else if (flags == strictConversion) {  
    100.         /* UTF-16 surrogate values are illegal in UTF-32 */  
    101.         if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {  
    102.         --source; /* return to the illegal value itself */  
    103.         result = sourceIllegal;  
    104.         break;  
    105.         }  
    106.     }  
    107.     if (target >= targetEnd) {  
    108.         source = oldSource; /* Back up source pointer! */  
    109.         result = targetExhausted; break;  
    110.     }  
    111.     *target++ = ch;  
    112.     }  
    113.     *sourceStart = source;  
    114.     *targetStart = target;  
    115. #ifdef CVTUTF_DEBUG  
    116. if (result == sourceIllegal) {  
    117.     fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x/n", ch, ch2);  
    118.     fflush(stderr);  
    119. }  
    120. #endif  
    121.     return result;  
    122. }  
    123.   
    124. /* --------------------------------------------------------------------- */  
    125.   
    126. /* 
    127.  * Index into the table below with the first byte of a UTF-8 sequence to 
    128.  * get the number of trailing bytes that are supposed to follow it. 
    129.  * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is 
    130.  * left as-is for anyone who may want to do such conversion, which was 
    131.  * allowed in earlier algorithms. 
    132.  */  
    133. static const char trailingBytesForUTF8[256] = {  
    134.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
    135.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
    136.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
    137.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
    138.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
    139.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  
    140.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  
    141.     2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5  
    142. };  
    143.   
    144. /* 
    145.  * Magic values subtracted from a buffer value during UTF8 conversion. 
    146.  * This table contains as many values as there might be trailing bytes 
    147.  * in a UTF-8 sequence. 
    148.  */  
    149. static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL,   
    150.              0x03C82080UL, 0xFA082080UL, 0x82082080UL };  
    151.   
    152. /* 
    153.  * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed 
    154.  * into the first byte, depending on how many bytes follow.  There are 
    155.  * as many entries in this table as there are UTF-8 sequence types. 
    156.  * (I.e., one byte sequence, two byte... etc.). Remember that sequencs 
    157.  * for *legal* UTF-8 will be 4 or fewer bytes total. 
    158.  */  
    159. static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };  
    160.   
    161. /* --------------------------------------------------------------------- */  
    162.   
    163. /* The interface converts a whole buffer to avoid function-call overhead. 
    164.  * Constants have been gathered. Loops & conditionals have been removed as 
    165.  * much as possible for efficiency, in favor of drop-through switches. 
    166.  * (See "Note A" at the bottom of the file for equivalent code.) 
    167.  * If your compiler supports it, the "isLegalUTF8" call can be turned 
    168.  * into an inline function. 
    169.  */  
    170.   
    171. /* --------------------------------------------------------------------- */  
    172.   
    173. ConversionResult ConvertUTF16toUTF8 (  
    174.     const UTF16** sourceStart, const UTF16* sourceEnd,   
    175.     UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {  
    176.     ConversionResult result = conversionOK;  
    177.     const UTF16* source = *sourceStart;  
    178.     UTF8* target = *targetStart;  
    179.     while (source < sourceEnd) {  
    180.     UTF32 ch;  
    181.     unsigned short bytesToWrite = 0;  
    182.     const UTF32 byteMask = 0xBF;  
    183.     const UTF32 byteMark = 0x80;   
    184.     const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */  
    185.     ch = *source++;  
    186.     /* If we have a surrogate pair, convert to UTF32 first. */  
    187.     if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {  
    188.         /* If the 16 bits following the high surrogate are in the source buffer... */  
    189.         if (source < sourceEnd) {  
    190.         UTF32 ch2 = *source;  
    191.         /* If it's a low surrogate, convert to UTF32. */  
    192.         if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {  
    193.             ch = ((ch - UNI_SUR_HIGH_START) << halfShift)  
    194.             + (ch2 - UNI_SUR_LOW_START) + halfBase;  
    195.             ++source;  
    196.         } else if (flags == strictConversion) { /* it's an unpaired high surrogate */  
    197.             --source; /* return to the illegal value itself */  
    198.             result = sourceIllegal;  
    199.             break;  
    200.         }  
    201.         } else { /* We don't have the 16 bits following the high surrogate. */  
    202.         --source; /* return to the high surrogate */  
    203.         result = sourceExhausted;  
    204.         break;  
    205.         }  
    206.     } else if (flags == strictConversion) {  
    207.         /* UTF-16 surrogate values are illegal in UTF-32 */  
    208.         if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {  
    209.         --source; /* return to the illegal value itself */  
    210.         result = sourceIllegal;  
    211.         break;  
    212.         }  
    213.     }  
    214.     /* Figure out how many bytes the result will require */  
    215.     if (ch < (UTF32)0x80) {       bytesToWrite = 1;  
    216.     } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;  
    217.     } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;  
    218.     } else if (ch < (UTF32)0x110000) {  bytesToWrite = 4;  
    219.     } else {                bytesToWrite = 3;  
    220.                         ch = UNI_REPLACEMENT_CHAR;  
    221.     }  
    222.   
    223.     target += bytesToWrite;  
    224.     if (target > targetEnd) {  
    225.         source = oldSource; /* Back up source pointer! */  
    226.         target -= bytesToWrite; result = targetExhausted; break;  
    227.     }  
    228.     switch (bytesToWrite) { /* note: everything falls through. */  
    229.         case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;  
    230.         case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;  
    231.         case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;  
    232.         case 1: *--target =  (UTF8)(ch | firstByteMark[bytesToWrite]);  
    233.     }  
    234.     target += bytesToWrite;  
    235.     }  
    236.     *sourceStart = source;  
    237.     *targetStart = target;  
    238.     return result;  
    239. }  
    240.   
    241. /* --------------------------------------------------------------------- */  
    242.   
    243. /* 
    244.  * Utility routine to tell whether a sequence of bytes is legal UTF-8. 
    245.  * This must be called with the length pre-determined by the first byte. 
    246.  * If not calling this from ConvertUTF8to*, then the length can be set by: 
    247.  *  length = trailingBytesForUTF8[*source]+1; 
    248.  * and the sequence is illegal right away if there aren't that many bytes 
    249.  * available. 
    250.  * If presented with a length > 4, this returns false.  The Unicode 
    251.  * definition of UTF-8 goes up to 4-byte sequences. 
    252.  */  
    253.   
    254. static Boolean isLegalUTF8(const UTF8 *source, int length) {  
    255.     UTF8 a;  
    256.     const UTF8 *srcptr = source+length;  
    257.     switch (length) {  
    258.     defaultreturn false;  
    259.     /* Everything else falls through when "true"... */  
    260.     case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;  
    261.     case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false;  
    262.     case 2: if ((a = (*--srcptr)) > 0xBF) return false;  
    263.   
    264.     switch (*source) {  
    265.         /* no fall-through in this inner switch */  
    266.         case 0xE0: if (a < 0xA0) return falsebreak;  
    267.         case 0xED: if (a > 0x9F) return falsebreak;  
    268.         case 0xF0: if (a < 0x90) return falsebreak;  
    269.         case 0xF4: if (a > 0x8F) return falsebreak;  
    270.         default:   if (a < 0x80) return false;  
    271.     }  
    272.   
    273.     case 1: if (*source >= 0x80 && *source < 0xC2) return false;  
    274.     }  
    275.     if (*source > 0xF4) return false;  
    276.     return true;  
    277. }  
    278.   
    279. /* --------------------------------------------------------------------- */  
    280.   
    281. /* 
    282.  * Exported function to return whether a UTF-8 sequence is legal or not. 
    283.  * This is not used here; it's just exported. 
    284.  */  
    285. Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {  
    286.     int length = trailingBytesForUTF8[*source]+1;  
    287.     if (source+length > sourceEnd) {  
    288.     return false;  
    289.     }  
    290.     return isLegalUTF8(source, length);  
    291. }  
    292.   
    293. /* --------------------------------------------------------------------- */  
    294.   
    295. ConversionResult ConvertUTF8toUTF16 (  
    296.     const UTF8** sourceStart, const UTF8* sourceEnd,   
    297.     UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {  
    298.     ConversionResult result = conversionOK;  
    299.     const UTF8* source = *sourceStart;  
    300.     UTF16* target = *targetStart;  
    301.     while (source < sourceEnd) {  
    302.     UTF32 ch = 0;  
    303.     unsigned short extraBytesToRead = trailingBytesForUTF8[*source];  
    304.     if (source + extraBytesToRead >= sourceEnd) {  
    305.         result = sourceExhausted; break;  
    306.     }  
    307.     /* Do this check whether lenient or strict */  
    308.     if (! isLegalUTF8(source, extraBytesToRead+1)) {  
    309.         result = sourceIllegal;  
    310.         break;  
    311.     }  
    312.     /* 
    313.      * The cases all fall through. See "Note A" below. 
    314.      */  
    315.     switch (extraBytesToRead) {  
    316.         case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */  
    317.         case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */  
    318.         case 3: ch += *source++; ch <<= 6;  
    319.         case 2: ch += *source++; ch <<= 6;  
    320.         case 1: ch += *source++; ch <<= 6;  
    321.         case 0: ch += *source++;  
    322.     }  
    323.     ch -= offsetsFromUTF8[extraBytesToRead];  
    324.   
    325.     if (target >= targetEnd) {  
    326.         source -= (extraBytesToRead+1); /* Back up source pointer! */  
    327.         result = targetExhausted; break;  
    328.     }  
    329.     if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */  
    330.         /* UTF-16 surrogate values are illegal in UTF-32 */  
    331.         if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {  
    332.         if (flags == strictConversion) {  
    333.             source -= (extraBytesToRead+1); /* return to the illegal value itself */  
    334.             result = sourceIllegal;  
    335.             break;  
    336.         } else {  
    337.             *target++ = UNI_REPLACEMENT_CHAR;  
    338.         }  
    339.         } else {  
    340.         *target++ = (UTF16)ch; /* normal case */  
    341.         }  
    342.     } else if (ch > UNI_MAX_UTF16) {  
    343.         if (flags == strictConversion) {  
    344.         result = sourceIllegal;  
    345.         source -= (extraBytesToRead+1); /* return to the start */  
    346.         break/* Bail out; shouldn't continue */  
    347.         } else {  
    348.         *target++ = UNI_REPLACEMENT_CHAR;  
    349.         }  
    350.     } else {  
    351.         /* target is a character in range 0xFFFF - 0x10FFFF. */  
    352.         if (target + 1 >= targetEnd) {  
    353.         source -= (extraBytesToRead+1); /* Back up source pointer! */  
    354.         result = targetExhausted; break;  
    355.         }  
    356.         ch -= halfBase;  
    357.         *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);  
    358.         *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);  
    359.     }  
    360.     }  
    361.     *sourceStart = source;  
    362.     *targetStart = target;  
    363.     return result;  
    364. }  
    365.   
    366. /* --------------------------------------------------------------------- */  
    367.   
    368. ConversionResult ConvertUTF32toUTF8 (  
    369.     const UTF32** sourceStart, const UTF32* sourceEnd,   
    370.     UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) {  
    371.     ConversionResult result = conversionOK;  
    372.     const UTF32* source = *sourceStart;  
    373.     UTF8* target = *targetStart;  
    374.     while (source < sourceEnd) {  
    375.     UTF32 ch;  
    376.     unsigned short bytesToWrite = 0;  
    377.     const UTF32 byteMask = 0xBF;  
    378.     const UTF32 byteMark = 0x80;   
    379.     ch = *source++;  
    380.     if (flags == strictConversion ) {  
    381.         /* UTF-16 surrogate values are illegal in UTF-32 */  
    382.         if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {  
    383.         --source; /* return to the illegal value itself */  
    384.         result = sourceIllegal;  
    385.         break;  
    386.         }  
    387.     }  
    388.     /* 
    389.      * Figure out how many bytes the result will require. Turn any 
    390.      * illegally large UTF32 things (> Plane 17) into replacement chars. 
    391.      */  
    392.     if (ch < (UTF32)0x80) {       bytesToWrite = 1;  
    393.     } else if (ch < (UTF32)0x800) {     bytesToWrite = 2;  
    394.     } else if (ch < (UTF32)0x10000) {   bytesToWrite = 3;  
    395.     } else if (ch <= UNI_MAX_LEGAL_UTF32) {  bytesToWrite = 4;  
    396.     } else {                bytesToWrite = 3;  
    397.                         ch = UNI_REPLACEMENT_CHAR;  
    398.                         result = sourceIllegal;  
    399.     }  
    400.       
    401.     target += bytesToWrite;  
    402.     if (target > targetEnd) {  
    403.         --source; /* Back up source pointer! */  
    404.         target -= bytesToWrite; result = targetExhausted; break;  
    405.     }  
    406.     switch (bytesToWrite) { /* note: everything falls through. */  
    407.         case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;  
    408.         case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;  
    409.         case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;  
    410.         case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);  
    411.     }  
    412.     target += bytesToWrite;  
    413.     }  
    414.     *sourceStart = source;  
    415.     *targetStart = target;  
    416.     return result;  
    417. }  
    418.   
    419. /* --------------------------------------------------------------------- */  
    420.   
    421. ConversionResult ConvertUTF8toUTF32 (  
    422.     const UTF8** sourceStart, const UTF8* sourceEnd,   
    423.     UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {  
    424.     ConversionResult result = conversionOK;  
    425.     const UTF8* source = *sourceStart;  
    426.     UTF32* target = *targetStart;  
    427.     while (source < sourceEnd) {  
    428.     UTF32 ch = 0;  
    429.     unsigned short extraBytesToRead = trailingBytesForUTF8[*source];  
    430.     if (source + extraBytesToRead >= sourceEnd) {  
    431.         result = sourceExhausted; break;  
    432.     }  
    433.     /* Do this check whether lenient or strict */  
    434.     if (! isLegalUTF8(source, extraBytesToRead+1)) {  
    435.         result = sourceIllegal;  
    436.         break;  
    437.     }  
    438.     /* 
    439.      * The cases all fall through. See "Note A" below. 
    440.      */  
    441.     switch (extraBytesToRead) {  
    442.         case 5: ch += *source++; ch <<= 6;  
    443.         case 4: ch += *source++; ch <<= 6;  
    444.         case 3: ch += *source++; ch <<= 6;  
    445.         case 2: ch += *source++; ch <<= 6;  
    446.         case 1: ch += *source++; ch <<= 6;  
    447.         case 0: ch += *source++;  
    448.     }  
    449.     ch -= offsetsFromUTF8[extraBytesToRead];  
    450.   
    451.     if (target >= targetEnd) {  
    452.         source -= (extraBytesToRead+1); /* Back up the source pointer! */  
    453.         result = targetExhausted; break;  
    454.     }  
    455.     if (ch <= UNI_MAX_LEGAL_UTF32) {  
    456.         /* 
    457.          * UTF-16 surrogate values are illegal in UTF-32, and anything 
    458.          * over Plane 17 (> 0x10FFFF) is illegal. 
    459.          */  
    460.         if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {  
    461.         if (flags == strictConversion) {  
    462.             source -= (extraBytesToRead+1); /* return to the illegal value itself */  
    463.             result = sourceIllegal;  
    464.             break;  
    465.         } else {  
    466.             *target++ = UNI_REPLACEMENT_CHAR;  
    467.         }  
    468.         } else {  
    469.         *target++ = ch;  
    470.         }  
    471.     } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */  
    472.         result = sourceIllegal;  
    473.         *target++ = UNI_REPLACEMENT_CHAR;  
    474.     }  
    475.     }  
    476.     *sourceStart = source;  
    477.     *targetStart = target;  
    478.     return result;  
    479. }  
    480.   

    展开全文
  • UTF8,ANSI,UTF7,UNICODE,UTF32等字符集字符串与字节数组互转工具,方便调试学习
  • unicode 表示 从 Unicode 历史到 UTF8/UTF16/UTF32 编码,然后从程序员的角度来看标准的波斯键盘布局 您可以从 下载我在上[波斯语] 的演示文稿中的视频!
  • UTF8、UTF16、UTF32都是unicode字符集的字符编码。 UTF意思是unicode转换格式(Unicode transform format),出现UTF8、UTF16、UTF32是出于要在内存中存储字符的目的而对unicode字符编号进行编码。 UTF8、UTF16、UTF...
    1. UTF8、UTF16、UTF32都是unicode字符集的字符编码。
    2. UTF意思是unicode转换格式(Unicode transform format),出现UTF8、UTF16、UTF32是出于要在内存中存储字符的目的而对unicode字符编号进行编码。
    3. UTF8、UTF16、UTF32区别:(8、16、32可看做每种字符编码存储所需的最少的比特位数)
    • UTF8:存在单字节编码,兼容ASCII;当编码为一个字节,则设最高比特位为0;当编码超过一个字节,则需要几个字节,就在第一个字节从最高位开始令连续的几个比特位为1,之后的字节最高位为10。UTF8:存在单字节编码,兼容ASCII;当编码为一个字节,则设最高比特位为0;当编码超过一个字节,则需要几个字节,就在第一个字节从最高位开始令连续的几个比特位为1,之后的字节最高位为10。
    • UTF32:用固定长度的字节存储字符编码,不管Unicode字符编号需要几个字节,全部都用4个字节存储,直接存储Unicode编号。无需经过字符编号向字符编码的转换步骤,提高效率,用空间换时间。
    • UTF16:使用2或4个字节进行存储。对于Unicode编号范围在0~FFFF之间的字符,统一用两个字节存储,无需字符转换,直接存储Unicode编号。对于Unicode字符编号在10000-10FFFF之间的字符,UTF16用四个字节存储,简单说就是:将Unicode字符编号(3字节)分为两部分,高位部分(Unicode字符编号中占1.5个字节)用一个值介于 D800-DBFF (110110yy yyyyyyyy,y为0/1)之间的双字节存储,低位部分用一个值介于 DC00-DFFF (110111xx xxxxxxxx,x为0/1)的双字节存储。而介于D800-DFFF之间的编码在Unicode中是预留的,不安排字符,如果Unicode中有字符的编号是这之间的值,会引发冲突和歧义,很有可能一个不常见字符(存储为四个字节)最后被读成两个常见字符(存储为两个字节)。
    1. 感悟来源于https://blog.csdn.net/guxiaonuan/article/details/78678043
    展开全文
  • 关于这个问题困惑了很长时间,主要原因是在理解“字节序”时,将“解码”也考虑进来了,在这里将解码也一并解答。...我们经常会想utf8是多字节编码,怎么就不会存在字节序问题,这一条就很好的解答这个问...
  • UTF-8 UTF-16 UTF-32转换代码 C语言编写
  • Unicode 和 UTF-8、UTF-16、UTF-32之间的关系

    千次阅读 多人点赞 2019-03-15 21:41:05
    Unicode 和 UTF-8、UTF-16、UTF-32之间的关系 要厘清它们之间的关系就要先从编码开始说起: ASCII码 我们都知道,在计算机的世界里,信息的表示方式只有 0 和 1,但是我们人类信息表示的方式却与之大不相同,很多时候...
  • UTF-8、UTF-16、UTF-32编码的相互转换

    千次阅读 2017-10-31 11:45:44
    最近在考虑写一个可以跨平台的通用字符串类,首先需要搞定的就是编码转换问题。 vs默认保存代码文件,使用的是本地code(中文即GBK,日文即Shift-JIS),也可以使用...gcc则是UTF-8,有无BOM均可(源代码的字符集
  • <br />UTF8,UTF16,UTF32,UTF16-LE,UTF16-BE,GBK 之间的转换 收藏  UTF8,UTF16,UTF32,UTF16-LE,UTF16-BE,GBK 之间的转换    Unicode是Unicode.org制定的编码标准,目前得到了绝大部分操作...
  • Unicode、ASCII、UTF7、UTF8、UTF16、UTF32

    千次阅读 2011-12-27 13:52:36
    其他实现方式还包括UTF-16和UTF-32,不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。 UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个...
  • 字符编码的概念(UTF-8、UTF-16、UTF-32都是什么鬼)

    万次阅读 多人点赞 2017-11-30 17:11:56
    2) UTF-32 UTF-32 是固定长度的编码,始终占用 4 个字节,足以容纳所有的 Unicode 字符,所以直接存储 Unicode 编号即可,不需要任何编码转换。浪费了空间,提高了效率。 3) UTF-16 UFT-16 比较奇葩,它使用 2 个...
  • utf-32是定长编码方案,它的编码单元是32-bit,同utf-16,编码单元都超过1个字节,所以需要指定bom,utf-32BE、utf-32LE 简单概括一下,其实utf-8、utf-16、utf-32都可以没有bom,只要传送端跟接收端一致即可,...
  • }#define DECLARE_WCS2UTF16CONV int _len; (_len); wchar_t * _wcs; (_wcs); unsigned short * _utf16; (_utf16) #define WCS2UTF16(wcs) / (((_wcs = wcs) == NULL) ? NULL : (/ _len = (utf16len(_...
  • 本人总结的最全字符编码概述,分享学习,涉及ACSII,GB2312,GBK,GB18030,Unicode,UTF8,UTF16,UTF32,BOM。 在做总结时被问到字符编码的知识,由于这块知识没有系统的学习过,所以答的不好,后来本人对字符...
  • Win32 UTF-8包装器 为什么要包装? 该库是从的需要演变为使用ANSI函数将Win32 API的Unicode功能破解为游戏的。 通过简单地包括win32_utf8.h并链接到该库,您就可以在使用本机Win32 API的应用程序中自动具有Unicode...
  • C++在C11标准中加入了对Unicode编码的支持,新增了wchar_t、char16_t、char32_t内置数据类型。  cout &lt;&lt; sizeof(char) &lt;&lt; endl;  cout &lt;&lt; sizeof(wchar_t) &lt;&...
  • STM32 MDK utf8 gbk编码转换;keil默认gbk编码,而网络传输默认utf8,遇到中文就会乱码
  • 8 utf8-32转码

    2014-03-28 23:36:34
    8 utf8-32转码 vb入门级代码教程 轻松学vb从我做起
  • Unicode详解(附UTF-8、UTF-16和UTF-32

    千次阅读 2019-08-16 14:26:44
    UTF-16 UTF-16介于UTF-8和UTF-32之间,它同时结合了定长和边长两种编码方式的特点, 它的编码规则很简单:基本平面的字符占用2个字节,辅助平面的字符占用4个字节。也就是说,UTF-16的编码长度要么是2个字节(U+...
  • 1.ascII码。 0x0*******; 总共127个。 有英文字母和符号。 好吧,问题来了。英文够用了,其他不够用啊。于是用两种方法解决:  ...a)GB2312 GBK 这一类的编码方式,用两位(2的16次方中变幻)来...UTF-8,UTF-16,...
  • UTF32Encoding -- 20000 繁体中文(CNS) x-Chinese-CNS DBCSCodePageEncoding -- 20001 TCA 台湾 x-cp20001 DBCSCodePageEncoding -- 20002 繁体中文(Eten...
  • 在keil开发过程中,有的情况下文件必须是utf8格式,如果不是utf8格式,编译出来运行起来是乱码,但是keil默认情况下编译不支持utf8格式的文件。网上到处的说法是增加no-multibyte-chars选项,但是作为初学者,不知道...
  • 这是转载自网络上的博文,UTF-8,UTF-16,UTF-32编码方式都是UNICODE,但只是他们的保存方式不同。 Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 514,506
精华内容 205,802
关键字:

utf32

友情链接: cmake_Lake_near.zip