字符编码的了解

news2024/11/25 10:14:49

前言:

        在编写文件读取功能的过程中,我遭遇了一个棘手的乱码难题。经过细致的排查,发现这一问题的根源在于文件的字符编码。为了帮助大家有效地克服编码差异所带来的开发挑战,因此,我收集了字符集编码的相关知识,并撰写了这篇博客,旨在帮助大家加深对字符编码的了解。

解释字符编码(概念)

        人类在与计算机交互时,用的都是人类能读懂的字符,如中文字符、英文字符、日文字符等

而计算机只能识别二进制数。

  • 二进制数即由0和1组成的数字,例如010010101010。
  • 计算机是基于电工作的,电的特性即高低电平,人类从逻辑层面将高电平对应为数字1,低电平对应为数字0,这直接决定了计算机可以识别的是由0和1组成的数字

        毫无疑问,由人类的字符到计算机中的数字,必须经历一个过程,如下

        翻译的过程必须参照一个特定的标准,该标准称之为字符编码表,该表上存放的就是字符与数字一一对应的关系。

        分享一个在线编码转换平台:        汉字字符集编码查询;中文字符集编码:GB2312、BIG5、GBK、GB18030、Unicode

常用字符编码一览表:

编码制定时间作用所占字节
ASCII1963表示英文字符和控制字符1个字节/字符
Unicode1991提供一个唯一编号给世界上的每一个字符,实现文本的国际化

UTF-8: 1-4个字节/字符

UTF-16: 2或4个字节/字符

UTF-32: 4个字节/字符

GB23121980表示简体中文字符以及一部分特殊字符和国际字符

1个字节表示英文字符

2个字节表示中文字符

GBK1993扩展和替代了 GB2312,包括更多中文字符

1个字节表示英文字符

2个字节表示中文字符

GB180302000扩展和替代了 GBK,包括更多中文字符,并且与Unicode 兼容

1个字节表示英文字符

2-4个字节表示中文字符

Big51984表示繁体中文字符

1个字节表示英文字符

2个字节表示中文字符

ISO 8859-11985表示西欧语言字符1个字节/字符
Windows-12521992主要用于西欧语言,包含一些特殊符号1个字节/字符
EUC-KR80年代用于编码韩文字符1-2个字节/字符
EUC-JP80年代用于编码日文字符1-2个字节/字符
Shift_JIS1997主要用于表示日文字符1个字节表示英文字符,1-2个字节表示日文字符

不同字符编码的需求:
        由于世界上有成千上万的语言和方言,因此需要不同的字符编码来准确地表示各种语言中的字符。

发展历史原因一览表:

字符编码: 

ASCII编码(基础)

ASCII的起源和应用
        ASCII编码,由美国标准协会(ASA)于1963年首次发布,是最早的字符编码标准。它能够编码英文字符和控制字符,广泛应用于各类计算机设备和通信协议中。

        现代计算机起源于美国,所以最先考虑仅仅是让计算机识别英文字符,于是诞生了ASCII。ASCII可以表示128个字符,包括英文字母、数字、标点符号以及控制字符。

中文字符编码(关注)

GB2312编码:1981年5月1日实施的简体中文汉字编码国家标准。GB2312对汉字采用双字节编码,收录7445个图形字符,其中包括6763个汉字。自2017年3月23日起,该标准转化为推荐性标准:GB/T2312-1980,不再强制执行。

GBK编码:1995年12月发布的汉字编码国家标准,是对GB2312编码的扩充,对汉字采用双字节编码。GBK字符集共收录21003个汉字,包含国家标准GB13000-1中的全部中日韩汉字,和BIG5编码中的所有汉字。

GB18030编码:2000年3月17日发布的汉字编码国家标准,是对GBK编码的扩充,覆盖中文、日文、朝鲜语和中国少数民族文字,其中收录27484个汉字。GB18030字符集采用单字节、双字节和四字节三种方式对字符编码。兼容GBK和GB2312字符集。2005年11月8日,发布了修订版本:GB18030-2005,共收录汉字七万余个。2022年7月19日,发布了第二次修订版本:GB18030-2022,收录汉字总数八万余个。

BIG5编码:台湾地区繁体中文标准字符集,采用双字节编码,共收录13053个中文字,1984年实施,主要用于台湾和香港。

Unicode编码(重点)

Unicode的产生背景

        Unicode应运而生,旨在创建一个全球统一的字符编码方案,使得各种语言和字符集能够在同一套编码体系下得到统一和标准化的处理。
        Unicode提供了多种编码方案,如UTF-8、UTF-16和UTF-32,以适应不同的应用需求和优化存储。

Unicode的特点:

#1. 存在所有语言中的所有字符与数字的一一对应关系,即兼容万国字符

#2. 与传统的字符编码的二进制数都有对应关系,详解如下

特点2:软件是存放于硬盘的,而运行软件是要将软件加载到内存的,面对硬盘中存放的各种传统编码的软件,想让我们的计算机能够将它们全都正常运行而不出现乱码,内存中必须有一种兼容万国的编码,并且该编码需要与其他编码有相对应的映射/转换关系,这就是unicode的第二大特点产生的缘由 

了解编码和解码概念:

        由字符转换成内存中的unicode,以及由unicode转换成其他编码的过程,都称为编码encode

        由内存中的unicode转换成字符,以及由其他编码转换成unicode的过程,都称为解码decode

编码方案(UTF-8、UTF-16、UTF-32):

Unicode 的目标?

        Unicode 的主要目标是为世界上的每一个字符提供一个唯一的数字标识,称为代码点。这意味着它不仅包括从各种语言的字母和数字,还包括符号、标点、特殊字符等。这是一个非常宏大的任务,因为世界上的书写系统和符号非常多。

存储和传输的挑战!

        如果我们为每一个 Unicode 字符都使用固定的字节数来存储和传输,那么对于那些只需要少量字符编码空间的文本(例如只使用 ASCII 字符的文本)来说,这将是非常浪费空间的。例如,使用 UTF-32,每个字符需要 4 个字节,这对于纯 ASCII 文本来说是非常浪费的。

        相反,如果我们选择一种对所有字符都足够小的编码(例如每个字符 1 字节),那么我们将无法表示大于 256 个字符的 Unicode 范围,这显然是不够的。

为什么需要多种编码方案?

        不同的编码方案试图在字符的全球性和存储/传输的效率之间找到平衡。

  • UTF-8 是变长的,它为 ASCII 字符使用 1 个字节,但可以为其他字符使用多达 4 个字节。这使得它非常适合于包含大量 ASCII 字符的文本,因为这些字符在 UTF-8 中的表示非常紧凑。

  • UTF-16 对许多常用的字符使用 2 个字节,但也可以使用 4 个字节。它对于那些常用字符大都位于基本多语言平面(BMP)的文本非常有效,如许多东亚语言。

  • UTF-32 为每个字符都使用 4 个字节,这提供了代码点到其编码的直接映射,简化了某些操作,但以空间为代价。

        因此,Unicode 提供了多种编码方案,以满足不同的需求和场景。选择哪种编码方案取决于特定的应用,包括文本的性质、需要执行的操作以及存储和传输的效率要求。

# 多国字符—√—》内存(unicode格式的二进制)——√—》硬盘(utf-8格式的二进制)

看图助解: 

其他亚洲字符编码(了解)

EUC-KR和EUC-JP的基本特性
        这两种编码是为了在计算机系统中表示韩文和日文字符而发展的,用于支持这两种语言的特定字符集。

Shift-JIS编码的应用
        Shift-JIS是一种日本字符编码,广泛用于日本的计算机系统和应用中。

扩展字符集(了解)

ISO 8859-1的介绍
        ISO 8859-1,也称为Latin-1,是为表示西欧语言字符而设计的一种字符编码。它扩展了基础的ASCII字符集,包含了256个字符。

Windows-1252的特点
        Windows-1252是Microsoft为西欧语言开发的一种字符编码,与ISO 8859-1非常相似,但在某些代码点上有所不同。

应用场景:

字符编码不匹配是产生乱码的一个重要原因。

  • 场景 1: 跨平台文件传输后出现乱码
  • 场景 2:Linux系统下中文乱码
  • 场景3:网页显示乱码
  • 场景 4: 文本编辑器打开文件乱码
  • 场景 5: 数据库存储或查询乱码

问题解决:

        博主的问题是在设计程序时未考虑读取GBK编码格式的数据从而导致的数据乱码现象。

处理思路如下:

1. 确定文件编码

  • 在大多数情况下,可能需要用户告知文件的编码,因为自动确定文本文件的编码可能是不准确的。
  • 自动检测编码(例如,只需要处理UTF-8和GBK),那么可以使用一些工具库(如uchardet)来自动检测编码。(实际效果不一定准确!)

2. 读取文件

  • 以二进制模式打开文件以确保数据的完整性。
  • 将整个文件(或一部分)读入内存。

3. 字符编码转换

  • 使用iconv或其他相似的库来将原始数据从其原始编码转换为目标编码(例如,从GBK转换为UTF-8)。
  • 为了提高效率,可以考虑一次转换一个缓冲区而不是整个文件,特别是对于大文件。

4. 处理转换后的数据

  • 现在,可以按照普通的方式处理转换后的数据,例如按行读取、解析等。
  • 如果在转换过程中遇到错误,确保有相应的错误处理机制。

5. 输出或存储数据

  • 将转换后的数据输出到屏幕、写入新文件或进行其他处理。

6. 关闭文件和清理资源

  • 关闭打开的文件。
  • 清理任何使用的资源或内存。

7. 异常处理

  • 为整个过程添加适当的异常处理和错误检查,确保能够优雅地处理如文件不存在、编码转换失败等问题。

8. 测试和验证

  • 使用多种编码格式和大小的文件对您的程序进行测试,确保它可以正确并有效地处理预期的输入。
  • 考虑边缘情况,如空文件、非常大的文件、包含奇怪字符的文件等。

注:具体的实现细节可能会根据实际需求和环境有所不同。

总结:

        尽管如今主流开发环境(众多开发工具、库)的默认字符编码为UTF-8,这确实为我们带来了不少便利。但正因如此,我们有时会在便利性中忽视某些细节。为了避免这类问题,我们还是需要对字符编码有更为全面和深入的了解。

       希望本篇内容能为您解决问题或提供有价值的参考。如果您有任何疑问或反馈,欢迎与我交流。感谢您的阅读与支持!

参考链接:9、字符编码 - 知乎

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

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

相关文章

想要精通算法和SQL的成长之路 - 旋转链表

想要精通算法和SQL的成长之路 - 旋转链表 前言一. 旋转链表 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 旋转链表 原题链接 由于k的大小可能超过链表长度,因此我们需要根据链表长度取模。那么我们首先需要去计算链表的长度是多少: if (head …

C# GraphicsPath 类学习

先在窗体放2个picturebox, 然后看一下如下代码; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; us…

Pytorch基础:Tensor的transpose方法

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 在Pytorch中,transpose是Tensor的一个重要方法,同时它也是一个torch模块中的一个函数,它们的语法如下所示。 Tensor.transpo…

window安装压缩版postgresql

环境: window 11 专业版postgresql-16.0-1-windows-x64-binaries.zip 一、下载 1.1 从官网下载 https://www.postgresql.org/download/windows/ 1.2 从百度网盘下载 链接:https://pan.baidu.com/s/1fmQbgWSzX4hN07Lgdzfz0g?pwddzyy 提取码&#…

汇编语言王爽第4版实验8答案(和你想的不一样)

实验8 分析一个奇怪的程序 E:\mywork\asm\p906.asm C:\>edit p906.asm assume cs:codecode segmentmov ax,4c00hint 21h start: mov ax,0 s:nop ; nop的机器码占一个字节nopmov di, offset smov si, offset s2mov ax, cs:[si]mov cs:[di],ax s0:jmp short s s1:mov ax,0in…

tauri为窗口添加阴影效果

需求 为窗口添加阴影效果,让窗口显得更立体。 实现方案 通过 tauri 中的 window-shadows 依赖实现。 编码 修改 label 标签内容 修改 src-tauri/tauri.conf.json 文件,设置 label 字段为 “customization” 增加shadows的依赖 修改 src-tauri…

第8期ThreadX视频教程:应用实战,将裸机工程移植到RTOS的任务划分,驱动和应用层交互,中断DMA,C库和中间件处理等注意事项

视频教程汇总帖:【学以致用,授人以渔】2023视频教程汇总,DSP第12期,ThreadX第8期,BSP驱动第26期,USB实战第5期,GUI实战第3期(2023-10-01) - STM32F429 - 硬汉嵌入式论坛 …

函数、函数的傅里叶级数展开、傅里叶级数的和函数之间的关系

1.函数、函数的傅里叶级数展开、傅里叶级数的和函数之间的关系 1.1 傅里叶级数中的系数公式推导 我们先来推导一下傅里叶级数中的系数公式,其实笔者已经写过一篇相关笔记,详见:为什么要把一个函数分解成三角函数?(傅利叶级数) f ( x )…

MySQL 索引优化实践(单表)

目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…

【数据结构】HashSet的底层数据结构

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 HashSet 一、 HashSet 集合的底层数据结构二…

GraphPad Prism 10 for Mac(统计分析绘图软件)

GraphPad Prism是一款专业的统计和绘图软件,主要用于生物医学研究、实验设计和数据分析。 以下是 GraphPad Prism 的主要功能和特点: 数据导入和整理:GraphPad Prism 可以导入各种数据格式,并提供直观的界面用于整理、编辑和管理数…

RFID与人工智能的融合:物联网时代的智能化变革

随着物联网技术的不断发展,现实世界与数字世界的桥梁已经被打通。物联网通过各种传感器,将现实世界中的光、电、热等信号转化为有价值的数据。这些数据可以通过RFID技术进行自动收集和传输,然后经由人工智能算法进行分析、建模和预测&#xf…

【LeetCode算法系列题解】第76~80题

CONTENTS LeetCode 76. 最小覆盖子串(困难)LeetCode 77. 组合(中等)LeetCode 78. 子集(中等)LeetCode 79. 单词搜索(中等) LeetCode 76. 最小覆盖子串(困难) …

Java下正面解除警告Unchecked cast: ‘java.lang.Object‘ to ‘java.util.ArrayList‘

就是我在反序列化时&#xff0c;遇到这样一个警告&#xff1a; Unchecked cast: java.lang.Object to java.util.ArrayList<com.work1.Student>然后我去网上查&#xff0c;有些人说用SuppressWarnings(“unchecked”)去忽略警告&#xff0c;但是我觉得作为一名合格的程序…

SNERT预备队招新CTF体验赛-Web(SWCTF)

目录 1、F12 2、robots 3、game1-喂青蛙 4、game 2 - flap bird 5、game 3 - Clash 6、Get&Post 7、sql &#xff08;1&#xff09;手工注入 &#xff08;2&#xff09;工具注入 8、命令执行漏洞 9、文件上传漏洞 10、文件泄露 11、php反序列化漏洞 12、PHP绕…

【网络编程】UDP数据报套接字编程和TCP流套接字编程

文章目录 1. 网络编程基础1.1 为什么需要网络编程&#xff1f;1.2 网络编程是什么&#xff1f;1.3 概念 2. Socket套接字3. UDP数据报套接字编程3.1 DatagramSocket API3.2 DatagramPacket API3.3 InetSocketAddress API 4. UDP构建服务端客户端&#xff08;一发一收&#xff0…

QSS之QComboBox

QComboBox在Qt开发过程中经常使用&#xff0c;默认的下载列表风格达不到设计师的要求&#xff0c;本篇介绍基本的QComboBox的qss设置。 属性意思QComboBoxQComboBox基本样式QComboBox:editable右边可选择按钮QComboBox:!editable, QComboBox::drop-down:editable不可编辑或下拉…

Python中匹配模糊的字符串

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 如何使用thefuzz 库&#xff0c;它允许我们在python中进行模糊字符串匹配。 此外&#xff0c;我们将学习如何使用process 模块&#xff0c;该模块允许我们在模糊…

离散数学 学习 之 5.3 一阶逻辑的推理理论

第一个证明中&#xff0c;最后三步的化简很重要&#xff0c;倒数第三步构造出一个可以化简出倒数第二步的公式&#xff0c;最后再化简 上面中的第 1&#xff0c; 2 步 和 3 &#xff0c; 4 步不能换&#xff0c;因为无法保证是同一个 c 尽量弄成前束范式 上面中2&#xff0c;3&…

无状态自动配置 DHCPv6无状态配置 DHCPv6有状态配置

1、无状态自动配置 配置命令 AR1 ipv6 #开启路由器ipv6报文转发功能 interface GigabitEthernet0/0/0 ipv6 enable #开启路由器接口IPv6报文转发功能 ipv6 address FC01::1/64 …