【计算机学习笔记】GB2312、GBK、Unicode等字符编码的理解

news2025/1/18 17:13:42

之前编写win32程序时没怎么关注过宽字符到底是个啥东西,最近在编写网络框架又遇到字符相关的问题,所以写一篇文章记录一下(有些部分属于个人理解,如果有错误欢迎指出)

目录

  • 几个常见的编码方式
  • Unicode和UTF-8、UTF-16、UTF-32的关系
  • 字符编码的应用
    • 文本文件里的字符
    • 编程中的字符
      • 字符串字面量
      • 高级语言的窄字符

几个常见的编码方式

  • GB2312:早期的汉字编码,覆盖6000+个常用汉字,无法处理生僻字或者古文
  • GBK:收录20000+个汉字和符号,包括繁体字生僻字等
  • GB18030:较新的汉字字集,与 GB 2312-1980 和 GBK 兼容,共收录汉字 70000+ 个,采用多字节编码,每个字可以由 1 个、2 个或 4 个字节组成
    GB2312GBK均属于2字节定长编码,和ASCII混编,ASCII区字符固定占用1字节,汉字区字符固定占用2字节
  • Unicode:为世界上所有字符都分配了一个唯一的数字编号,目前编号范围从 0x000000 到 0x10FFFF,一共17个平面,每个平面有65536个码点

Unicode和UTF-8、UTF-16、UTF-32的关系

Unicode只规定了每个字符的编号,但没有规定二进制码如何存储,而UTF-8、UTF-16、UTF-32就是Unicode的二进制存储实现方案

  • UTF-8:使用变长编码,编号小的使用的字节就少,编号大的使用的字节就多。使用的字节个数从 1 到 4 个不等,实现了对 ASCII 码的向后兼容,网络传输一般选择这种方式节省网络资源。编码规则:
    1. 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
    2. 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
    3. 例如在U+0080U+07FF之间的字符,UTF - 8 用 2 个字节来编码。其格式为110xxxxx 10xxxxxx。编码时,将 Unicode 码点的二进制表示分为两部分,前 5 位放在第一个字节的xxxxx位置,后 6 位放在第二个字节的xxxxxx位置。
  • UTF-16:使用变长编码
    1. 对于编号在U+0000U+FFFF的字符(常用字符集),直接用两个字节表示。
    2. 编号在U+10000U+10FFFF之间的字符,需要用四个字节表示。
    3. UTF-16有字节的顺序问题(大小端),所以就有 UTF-16BE 表示大端,UTF-16LE 表示小端。
    4. 会在字符开头添加FEFF(不知道干什么用,网上也找不到资料)
  • UTF-32:定长编码,直接将码点转换为4字节的二进制表示形式,消耗较大,用得比较少,同样也有字节顺序问题

字符编码的应用

文本文件里的字符

  • ANSI:在一些文本编辑器里(例如记事本)会看到ANSI编码方式。ANSI并不是某一种特定的字符编码,而是在不同的系统中,ANSI表示不同的编码,例如中国的计算机ANSI编码即为GBK,美国的计算机ANSI编码即为ASCII
    如下图所示, 记事本和rider编辑器右下角都会有显示此文件的编码方式
    记事本
    rider

在这些文本编辑器里选择转换编码方式的话,则文本的内容不变,改变编码方式。选择重新加载,则内存内容不变,重新以新的编码方式解析成文本

下面展示分别使用ANSI(GBK),UTF-8,UTF-16,UTF-32四种方式存储“你好我是123456”这个字符串所需大小:

  1. ANSI(GBK):汉字占2字节,ASCII字符占1字节
    在这里插入图片描述
  2. UTF-8:汉字占3字节,ASCII字符占1字节
    在这里插入图片描述
  3. UTF-16:汉字占2字节,ASCII字符占2字节,UTF-16还有在开头添加的2字节
    在这里插入图片描述
  4. UTF-32:每个字符4字节,因为记事本没有UTF32,我在Rider修改编码方式
    在这里插入图片描述
    用VS打断点测试一下大端序UTF-16的内存情况,下图为文本文件存储的22字节内容:
    在这里插入图片描述
    除了开头添加的FEFF,“你好我是”这四个汉字的Unicode编号分别为
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    可以发现和内存里汉字的内容和字符编码相对应,后面的31003200这些就不一个个查了

编程中的字符

  • C/C++中窄字符和宽字符共用,窄字符即string(char),宽字符即wstring(wchar_t),Python/C#这种高级语言里的string默认为宽字符
  • 窄字符字符串以单个字节为单位,输出长度是输出字节数;宽字符字符串以字符为单位,输出长度是输出字符数

字符串字面量

C++中存储窄字符串字面量的话,字符串编码方式和代码文本文件的编码方式有关,存储宽字符串字面量的话要在字符串前面加‘L’标记,在Python/C#之类的高级语言里则是直接存储宽字符的字面量
例如下面这一段C++代码,如果文件格式为GBK,则输出14,如果为UTF-8,则输出18

#include <iostream>

int main()
{
    std::string str = "你好我是123456";
    std::cout << str.size();

    return 0;
}

下面是C++,Python,C#代码分别存储宽字符并输出大小的代码:

#include <iostream>

int main()
{
    std::wstring str = L"你好我是123456";
    std::cout << str.size();

    return 0;
}

Rider中的C++输出

s = "你好我是123456"
print(len(s))

Pycharm中的Python输出

using UnityEngine;

public class StartUp : MonoBehaviour
{
    private void Start()
    {
        string str = "你好我是123456";
        Debug.Log(str.Length);
    }
}

在这里插入图片描述

高级语言的窄字符

刚刚说了,Python/C#这种高级语言的字符串默认采用宽字符,如果要在高级语言使用窄字符,则需要对字符串使用encode之类的函数变成高级语言的byte数组

print(len("你好我是123456".encode("utf-8")))
print(len("你好我是123456".encode("gbk")))

在这里插入图片描述

using System.Text;
using UnityEngine;

public class StartUp : MonoBehaviour
{
    private void Start()
    {
        string str = "你好我是123456";
        
        byte[] utf8Bytes = Encoding.GetEncoding("UTF-8").GetBytes(str);
        byte[] gbkBytes = Encoding.GetEncoding("GBK").GetBytes(str);
        
        Debug.Log("UTF-8编码后的长度" + utf8Bytes.Length);
        Debug.Log("GBK编码后的长度" + gbkBytes.Length);
    }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

七种msvcp140.dll丢失的解决方法及了解msvcp140.dll丢失的原因

在Windows操作系统中&#xff0c;msvcp140.dll是Microsoft Visual C 2015 Redistributable Package的一部分。这个动态链接库文件对于许多应用程序的正常运行至关重要&#xff0c;因为它包含了C程序所需的标准库函数。当用户遇到“msvcp140.dll丢失”或类似的错误信息时&#x…

QT4和 QT5 槽函数连接的区别

正常连接方式 //QT4官方用列QLabel *label new QLabel;QScrollBar *scrollBar new QScrollBar;QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)));//QT5官方用列QLabel *label new QLabel;QLineEdit *lineEdit new QLineEdit;QObject::c…

LeetCode - #152 乘积最大子数组(Top 100)

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 本题为 LeetCode 前 100 高频题 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 …

新手前端开发入职公司全流程

作为一名前端开发新手&#xff0c;进入一家公司开启职业生涯是既兴奋又充满挑战的旅程。今天就来和大家分享一下这个过程中的各个环节。 一、入职准备 在收到心仪公司的offer后&#xff0c;可别只顾着高兴啦。首先要准备好入职资料&#xff0c;像身份证、学历证明这些是必不可…

【深入探索 C++ STL 容器 list】 —— 编程世界的万能胶,数据结构中的百变精灵

STL系列学习参考&#xff1a; STL 数据结构与算法__Zwy的博客-CSDN博客https://blog.csdn.net/bite_zwy/category_12852141.html 学习C STL的三个境界&#xff0c;会用&#xff0c;明理&#xff0c;能扩展&#xff0c;STL中的所有容器都遵循这个规律&#xff0c;下面我们就按…

【数电】常见时序逻辑电路设计和分析

本文目的&#xff1a;一是对真题常考题型总结&#xff0c;二是对常见时序电路设计方法进行归纳&#xff0c;给后面看这个文档的人留有一点有价值的东西。 1.不同模计数器设计 2.序列信号产生和检测电路 2.1序列信号产生电路 2.1.1设计思路 主要设计思路有三种 1&#xff09…

MCU、ARM体系结构,单片机基础,单片机操作

计算机基础 计算机的组成 输入设备、输出设备、存储器、运算器、控制器 输入设备&#xff1a;将其他信号转换为计算机可以识别的信号&#xff08;电信号&#xff09;。输出设备&#xff1a;将电信号&#xff08;&#xff10;、&#xff11;&#xff09;转为人或其他设备能理解的…

数字图像处理考研考点(持续更新)

一、数字图像基本概念 1、人眼视觉特性 &#xff08;1&#xff09;眼睛上有两类光感受器&#xff1a;锥状体和杆状体 锥状体(锥细胞)&#xff1a;约 700 万个&#xff0c;对颜色高度敏感&#xff0c;每个锥状体都连接到神经末梢&#xff0c;人可以充分地分辨图像细节。锥细胞…

Lumos学习王佩丰Excel第二十讲:图表基础

Excel图表就像是把一堆复杂的数字变成了一幅幅直观的图画&#xff0c;让我们能够更快地理解数据之间的关系和趋势&#xff0c;使工作表更易于读懂和交流。学好这几节课&#xff0c;不仅可以辅助工作&#xff0c;还可以装X哈哈哈~~~ 一、认识图表中的元素&#xff08;七块积木&…

VTK知识学习(20)- 数据的存储与表达

1、数据的存储 1)、vtkDataArray VTK中的内存分配采用连续内存&#xff0c;可以快速地创建、删除和遍历&#xff0c;称之为数据数组(DataArray)&#xff0c;用类 vtkDataArray 实现。数组数据的访问是基于索引的&#xff0c;从零开始计数。 以 vtkFloatArray 类来说明如何在 …

如何在UI自动化测试中创建稳定的定位器?

如何在UI自动化测试中创建稳定的定位器&#xff1f; 前言1. 避免使用绝对路径2. 避免在定位器中使用索引3. 避免多个类名的定位器4. 避免动态和自动生成的ID5. 确保定位器唯一6. 处理隐藏元素的策略7. 谨慎使用基于文本的定位器8. 使用AI创建稳定的定位器 总结 前言 在自动化测…

SparkSQL 读写数据攻略:从基础到实战

目录 一、输入Source 1&#xff09;代码演示最普通的文件读取方式&#xff1a; 2&#xff09; 通过jdbc读取数据库数据 3) 读取table中的数据【hive】 二、输出Sink 实战一&#xff1a;保存普通格式 实战二&#xff1a;保存到数据库中 实战三&#xff1a;将结果保存在h…

【1】Python交叉编译到OpenHarmony标准系统运行(arm32位)

本文介绍如何Python语言如何在OpenHarmony标准系统运行,包括5.0r和4.1r以及4.0r,和未来版本的OpenHarmony版本上。 Python语言在OpenHarmony上使用,需要将Python解释器CPython移植到OpenHarmony标准系统。通过交叉编译的方式。 首先来了解几个概念: CPython 是 Python 编…

Windows环境中Python脚本开机自启动及其监控自启动

1 开机自启动 Windows 10/Windows Server 201X具有一个名为“启动”的已知文件夹&#xff0c;系统每次启动开始自动运行应用程序、快捷方式和脚本时都会检查该文件夹&#xff0c;而无需额外配置。 要在Windows启动时运行脚本&#xff0c;先使用WindowsR快捷键打开“运行”对话…

Mysql索引原理及优化——岁月云实战笔记

根据Mysql索引原理及优化这个博主的视频学习&#xff0c;对现在的岁月云项目中mysql进行优化&#xff0c;我要向这个博主致敬&#xff0c;之前应用居多&#xff0c;理论所知甚少&#xff0c;于是将学习到东西&#xff0c;应用下来&#xff0c;看看是否有好的改观。 1 索引原理…

JavaWeb学习(3)(Servlet详细、Servlet的三种实现方式(面试)、Servlet的生命周期、传统web.xml配置Servlet(了解))

目录 一、Servlet详细。 &#xff08;1&#xff09;基本介绍。 &#xff08;2&#xff09;基本作用。 1、接收客户端请求数据。 2、处理请求。 3、完成响应结果。 二、Servlet的三种实现方式。 &#xff08;1&#xff09;实现javax.servlet.Servlet接口。 1、基本介绍。 2、代码…

第6章:布局 --[CSS零基础入门]

CSS 布局是网页设计中至关重要的一个方面&#xff0c;它决定了页面上元素的排列和展示方式。以下是几种常见的 CSS 布局方法和技术&#xff1a; 1. 浮动布局&#xff08;Float Layout&#xff09; 浮动布局&#xff08;Float Layout&#xff09;曾经是网页设计中创建多列布局…

哪里可以找到高质量的街道夜景短视频素材?夜景素材网站推荐

在短视频创作的浪潮中&#xff0c;街道夜景作为一种视觉效果独特、氛围浓郁的题材&#xff0c;深受创作者的青睐。不论是商业广告、创意短片还是个人Vlog&#xff0c;街道夜景的视频素材都能为你的作品增添不小的分量。那么&#xff0c;在哪里可以找到这些高质量的街道夜景短视…

Unity类银河战士恶魔城学习总结(P166 Ailments FX 异常状态伤害粒子特效)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节创建了三种粒子特效&#xff0c;火焰&#xff0c;寒冰&#xff0c;雷电 主场景创建/特效/粒子 初始的例子特效 火焰 寒冰 雷电 En…

游戏引擎学习第38天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾上次的内容。 我们之前讨论了将精灵放在屏幕上&#xff0c;但颜色错误的问题。问题最终查明是因为使用了一个调整工具&#xff0c;导致文件的字节顺序发生了变化。重新运行“image magic”工具对一些大图像进行重新处理后&am…