字符编码认知、互相转换和C++代码判断是UTF8还是GBK

一、unicode编码基础认知

二、C++如何判断是否是UTF8编码

形式1:详见mozilla xpcom\string\nsReadableUtils.cpp:

只要有一个字符不满足UTF8判断条件,就返回false

bool
IsUTF8(const nsACString& aString, bool aRejectNonChar)
{nsReadingIterator<char> done_reading;aString.EndReading(done_reading);int32_t state = 0;bool overlong = false;bool surrogate = false;bool nonchar = false;uint16_t olupper = 0; // overlong byte upper bound.uint16_t slower = 0;  // surrogate byte lower bound.nsReadingIterator<char> iter;aString.BeginReading(iter);const char* ptr = iter.get();const char* end = done_reading.get();while (ptr < end) {uint8_t c;if (0 == state) {c = *ptr++;if (UTF8traits::isASCII(c)) {continue;}if (c <= 0xC1) { // [80-BF] where not expected, [C0-C1] for overlong.return false;} else if (UTF8traits::is2byte(c)) {state = 1;} else if (UTF8traits::is3byte(c)) {state = 2;if (c == 0xE0) { // to exclude E0[80-9F][80-BF]overlong = true;olupper = 0x9F;} else if (c == 0xED) { // ED[A0-BF][80-BF] : surrogate codepointsurrogate = true;slower = 0xA0;} else if (c == 0xEF) { // EF BF [BE-BF] : non-characternonchar = true;}} else if (c <= 0xF4) { // XXX replace /w UTF8traits::is4byte when it's updated to exclude [F5-F7].(bug 199090)state = 3;nonchar = true;if (c == 0xF0) { // to exclude F0[80-8F][80-BF]{2}overlong = true;olupper = 0x8F;} else if (c == 0xF4) { // to exclude F4[90-BF][80-BF]// actually not surrogates but codepoints beyond 0x10FFFFsurrogate = true;slower = 0x90;}} else {return false;  // Not UTF-8 string}}if (nonchar && !aRejectNonChar) {nonchar = false;}while (ptr < end && state) {c = *ptr++;--state;// non-character : EF BF [BE-BF] or F[0-7] [89AB]F BF [BE-BF]if (nonchar &&((!state && c < 0xBE) ||(state == 1 && c != 0xBF)  ||(state == 2 && 0x0F != (0x0F & c)))) {nonchar = false;}if (!UTF8traits::isInSeq(c) || (overlong && c <= olupper) ||(surrogate && slower <= c) || (nonchar && !state)) {return false;  // Not UTF-8 string}overlong = surrogate = false;}}return !state; // state != 0 at the end indicates an invalid UTF-8 seq.
}

形式二:C++ 标准版

bool IsUTF8(const void *pBuffer, int size)
{bool IsUTF8 = false;unsigned char *start = (unsigned char *)pBuffer;unsigned char *end = (unsigned char *)pBuffer + size;while (start < end){if (*start < 0x80) // (10000000): 值小于0x80的为ASCII字符 {start++;}else if (*start < (0xC0)) // (11000000): 值介于0x80与0xC0之间的为无效UTF-8字符 {IsUTF8 = false;break;}else if (*start < (0xE0)) // (11100000): 此范围内为2字节UTF-8字符 {IsUTF8 = true;if (start >= end - 1)break;if ((start[1] & (0xC0)) != 0x80){IsUTF8 = false;break;}start += 2;}else if (*start < (0xF0)) // (11110000): 此范围内为3字节UTF-8字符 {IsUTF8 = true;if (start >= end - 2) break;if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80){IsUTF8 = false; break;}start += 3;}else if (*start < (0xF8)) // (11111000): 此范围内为4字节UTF-8字符 {IsUTF8 = true;if (start >= end - 3) break;if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80 || (start[3] & (0xC0)) != 0x80){IsUTF8 = false; break;}start += 4;}else{IsUTF8 = false;break;}}return IsUTF8;
}

形式一、形式二都存在一定的缺陷:

例如 "通知"两个字的GB2312编码为:0xCD0xA8(通)、0xD60xAA(知) 使用这两种形式的代码都会被误判为是UTF8编码,具体那些字段会被误判,可查看GB2312编码表《CP936.TXT》

三、GBK编码基础认知

判断是否是GBK编码:

形式一、C++通用版本

bool isGBKCode(const string& strIn)
{unsigned int nBytes = 0;//GBK可用1-2个字节编码,中文两个 ,英文一个 unsigned char chr = strIn.at(0);bool bAllAscii = true; //如果全部都是ASCII,  for (unsigned int i = 0; strIn[i] != '\0'; ++i){chr = strIn.at(i);if ((chr & 0x80) != 0 && nBytes == 0){// 判断是否ASCII编码,如果不是,说明有可能是GBKbAllAscii = false;}if (nBytes == 0) {if (chr >= 0x80) {if (chr >= 0x81 && chr <= 0xFE){nBytes = +2;}else{return false;}nBytes--;}}else{if (chr < 0x40 || chr>0xFE){return false;}nBytes--;}//else end}if (nBytes != 0)  {     //违返规则 return false;}if (bAllAscii){ //如果全部都是ASCII, 也是GBKreturn true;}return true;
}

形式二、适合mozilla的代码如下:

bool
IsGBK(const nsACString& aString)
{nsReadingIterator<char> done_reading;aString.EndReading(done_reading);//GBK:英文字母和数字占用一个字节,特殊字符(如部分标点符号、//非常见字母等)仍占用两个字节,汉字编码占用两个字节。unsigned int nBytes = 0;bool bAllAscii = true; //如果为true,全部都是ASCIInsReadingIterator<char> iter;aString.BeginReading(iter);const char* ptr = iter.get();const char* end = done_reading.get();while (ptr < end) {uint8_t c;c = *ptr++;if ((c & 0x80) != 0 && nBytes == 0) {bAllAscii = false;}if (nBytes == 0) {if (c >= 0x80) {if (c >= 0x81 && c <= 0xFE) {nBytes = +2;} else {return false;}nBytes--;}} else {if (c < 0x40 || c > 0xFE) {return false;}nBytes--;}}if (nBytes != 0) {return false;}//如果全是ASCII码,就认为不是GBK,还是以UTF8编码为准,不改变原逻辑if (bAllAscii) {return false;}return true;
}

四、GB2312和UTF8互转

在该网站可看unicode编码库:

Index of /Public/MAPPINGS/VENDORS/MICSFT/WINDOWSicon-default.png?t=N7T8https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/

其中,CP936.TXT就是GB2312编码库; 该文档部分截图如下:

以"知"字为例:GB2312编码为:0xD6AA   对应的UTF8编码为 0x77E5;

在在线转换网站UTF-8编码转换 UTF-8转换工具 在线UTF-8编码汉字互转工具 iP138在线工具在线UTF-8编码汉字互转工具是一款可以帮助你把中文转换成UTF-8编码,同时也支持把UTF-8编码过的还原成中文的小工具。icon-default.png?t=N7T8https://tool.ip138.com/utf8/上可以互相转换:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/456751.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

仅一个月获推荐170w+,视频号近期爆火的秘诀是什么?

为了保证良好的创作环境&#xff0c;视频号的原创标准在1月做了新调整&#xff0c; 视频时长小于5秒则不能声明为原创 &#xff0c;纯图片轮播也不能声明为原创&#xff0c;只有持续输出优质内容的账号才能显示原创标识及原创保护功能&#xff0c;这样的改动也给了不少创作者…

C++进阶(十一)C++11

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、C11简介二、统一的列表初始化1、&#xff5b;&#xff5d;初始化2、std::initializer_lis…

苹果证书过期有什么影响

引言 苹果证书是一种数字签名&#xff0c;用于验证应用程序的身份和完整性。然而&#xff0c;若该证书过期&#xff0c;将会对用户和开发者带来一定的影响。在本文中&#xff0c;我们将详细介绍苹果证书过期的原理和影响&#xff0c;并提供一些解决方法。 苹果证书的原理 苹…

14.scala隐式转换

目录 概述实践代码执行结果 结束 概述 隐式转换&#xff1a;偷偷的(隐式)对现有功能进行增强(转换) 实践 代码 package com.fun.scalaimport java.io.File import scala.io.Sourceobject ImplicitApp {def main(args: Array[String]): Unit {// implicit 2 to 等价 &…

【Linux】Linux权限(下)

Hello everybody!在上一篇文章中&#xff0c;权限讲了大部分内容。今天继续介绍权限剩下的内容&#xff0c;希望大家看过这篇文章后都能有所收获&#xff01; 1.更改文件的拥有者和所属组 对于普通用户&#xff0c;文件的拥有者和所属组都无权修改。 、 、 但root可以修改文件…

Anaconda的安装及其配置

一、简介 Anaconda是一个开源的包、环境管理器&#xff0c;主要具有以下功能和特点&#xff1a; 提供conda包管理工具&#xff1a;可以方便地创建、管理和分享Python环境&#xff0c;用户可以根据自己的需要创建不同的环境&#xff0c;每个环境都可以拥有自己的Python版本、库…

Linux 服务器安装maven

1、压缩文件下载Maven – Download Apache Maven 2、解压 tar -xvf apache-maven-3.8.4-bin.tar.gz 3、配置环境变量 在/etc/profile中保存Maven的环境变量&#xff1a; export M2_HOME/opt/server/apache-maven-3.5.4 export PATH$PATH:$M2_HOME/bin 4、通过source生效文件 so…

FB-BEV:BEV Representation from Forward-Backward View Transformations

参考代码&#xff1a;FB-BEV 动机与出发点 基于几何关系的BEV投影过程&#xff0c;依据BEV特征获取方式进行划分&#xff1a;图像角度使用类似LSS方案“push”过程或者BEV特征角度使用类似Fast BEV方案的“pull”过程。前者产生的BEV特征是稀疏的矩阵&#xff0c;后者产生的BE…

Orange3数据转换(数据采样组件)

组件介绍&#xff1a; 固定数据比例&#xff08;Fixed proportion of data&#xff09; 返回整个数据的选定百分比 固定样本量(Fixed sample size) 返回选定数量的数据实例&#xff0c;并可以设置 Sample with replacement(替换样本)&#xff0c;该替换样本始终从整个数据集中…

MySQL查询优化技巧和10个案例展示

优化MySQL查询的实战技巧&#xff1a; **避免使用SELECT ***&#xff1a;只获取需要的列&#xff0c;这样可以减少数据传输量&#xff0c;提高查询效率。使用索引&#xff1a;为查询频繁的列创建索引&#xff0c;可以显著提高查询速度。但请注意&#xff0c;索引并非万能&…

c语言贪食蛇游戏

演示视频 目录 一.概述 二.游戏开始前 修改控制台程序标题和大小 Win32 API GetStdHandle函数 GetConsoleCursorInfo函数和SetConsoleCursorInfo函数 SetConsoleCursorPosition函数 游戏开篇界面处理 创建地图 蛇身节点以及食物节点初始化 蛇身的初始化 整体蛇节点…

万字猛文:MQTT原理及案例

MQTT 协议是当今世界上最受欢迎的物联网协议&#xff0c;没有之一。MQTT 协议为设备提供了稳定、可靠、简单易用的通信基础&#xff0c;截至目前通过 MQTT 协议连接的设备已经过亿&#xff0c;广泛应用于 IoT、M2M 等领域。本篇将从最基础的知识开始&#xff0c;向您讲解 MQTT …