解决中文乱码:字符编码全攻略 - ASCII、Unicode、UTF-8、GB2312详解

🧑 博主简介:CSDN博客专家历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程高并发设计Springboot和微服务,熟悉LinuxESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea

在这里插入图片描述


在这里插入图片描述

文章目录

  • 解决中文乱码:字符编码全攻略 - ASCII、Unicode、UTF-8、GB2312详解
      • 什么是中文乱码
      • 什么是字符编码
        • 1)ASCII
        • 2)Unicode
        • 3)UTF-8
        • 4)GB2312
      • 中文乱码是如何出现的?
      • 如何解决中文乱码呢?

解决中文乱码:字符编码全攻略 - ASCII、Unicode、UTF-8、GB2312详解

就在昨天,我在官网看到这样一张截图,有球友反馈说支付宝的理财页面出现了中文乱码,估计不少小伙伴和我一样,都惊呆了😮!阿里这种大厂还能出现这种低级错误?

难道昨天的人力都投入到“通义千问”的突然发布上了?

那借这个机会,我就来和大家探讨一下,中文乱码是怎么出现的,以及如何快速解决乱码问题。

什么是中文乱码

Q:什么是中文乱码?

GPT4:中文乱码是指在计算机系统或软件中,由于字符编码不一致或处理不当,导致中文字符无法正常显示,出现乱码现象。这种现象通常表现为中文字符被替换成其他不相关的字符、符号或乱码。

比如说,历史上著名的“锟斤拷”同学,就是中文乱码的绝佳代言人。

什么是字符编码

Q:那什么是字符编码呢?

GPT4:字符编码(Character Encoding)是一种规则或约定,它将字符(如字母、数字、标点符号等)映射到计算机中的二进制数据。简单来说,字符编码就是将人类可读的字符转换为计算机可以处理的二进制数据的过程。

对于计算机来说,只认 0 和 1,所有的信息最终都是一个二进制数。一个二进制数要么是 0,要么是 1。8 个二进制数放在一起是一个字节,就会组合出 256 种状态,也就是 2 的 8 次方(2^8),从 00000000 到 11111111。

为了让计算机能够识别和处理各种字符,需要使用字符编码来对字符进行编码和解码。常见的字符编码包括 ASCII、UTF-8、UTF-16、GBK、GB2312 等。

1)ASCII

ASCII 码由电报码发展而来,第一版标准发布于 1963 年,最后一次更新则是在 1986 年,至今为止共定义了 128 个字符。其中 33 个字符无法显示在一般的设备上,需要用特殊的设备才能显示。

ASCII 码的局限在于只能显示 26 个基本拉丁字母、阿拉伯数字和英式标点符号,因此只能用于显示现代美国英语,对于其他一些语言则无能无力,比如在法语中,字母上方有注音符号,它就无法用 ASCII 码表示。

PS:拉丁字母(也称为罗马字母)是多数欧洲语言采用的字母系统,是世界上最通行的字母文字系统,是罗马文明的成果之一。

虽然名称上叫作拉丁字母,但拉丁文中并没有用 J、U 和 W 这三个字母。

在我的印象中,可能说拉丁字母多少有些陌生,说英语字母可能就有直观的印象了。

阿拉伯数字,我们都很熟悉了。

但是,阿拉伯数字并非起源于阿拉伯,而是起源于古印度。学过历史的你应该有一些印象,阿拉伯分布于西亚和北非,以阿拉伯语为主要语言,以伊斯兰教为主要信仰。

处在这样的地理位置,做起东亚和欧洲的一些生意就很有优势,于是阿拉伯数字就由阿拉伯人传到了欧洲,因此得名。

英式标点符号,也叫英文标点符号,和中文标点符号很相近。标点符号是辅助文字记录语言的符号,是书面语的组成部分,用来表示停顿、加强语气等。

英文标点符号在 16 世纪时,分为朗诵学派和句法学派,主要由古典时期的希腊文和拉丁文演变而来,在 17 世纪后进入稳定阶段。俄文的标点符号依据希腊文而来,到了 18 世纪后也采用了英文标点符号。

在很多人的印象中,古文是没有标点符号的,但管锡华博士研究指出,中国早在先秦时代就有标点符号了,后来融合了一些英文标点符号后,逐渐形成了现在的中文标点符号。

2)Unicode

这个世界上,除了英语,还有法语、葡萄牙语、西班牙语、德语、俄语、阿拉伯语、韩语、日语等等等等。ASCII 码用来表示英语是绰绰有余的,但其他这些语言就没办法了。

像我的主人二哥的母语——中文,就博大精深,与其对应的汉字数量很多很多,东汉的《说文解字》收字 9353 个,清朝《康熙字典》收字 47035 个,当代的《汉语大字典》收字 60370 个。1994 年中华书局、中国友谊出版公司出版的《中华字海》收字 85568 个。

常用字大概 2500 个,次常用字 1000 个。

一个字节只能表示 256 种符号,所以如果拿 ASCII 码来表示汉字的话,是远远不够用的,那就必须要用更多的字节。简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,理论上最多可以表示 256 x 256 = 65536 个符号。

要知道,世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。

  • 编码就是将原始数据(比如说文本、图像、视频、音频等)转换为二进制形式。
  • 解码就是将二进制数据转换为原始数据,是一个反向的过程。

如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会彻底消失。

这个艰巨的任务由谁来完成呢?Unicode,中文译作万国码、国际码、统一码、单一码,就像它的名字都表示的,这是一种所有符号的编码。

Unicode 至今仍在不断增修,每个新版本都会加入更多新的字符。目前最新的版本为 2020 年 3 月公布的 13.0,收录了 13 万个字符。

Unicode 是一个很大的集合,现在的规模可以容纳 100 多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母 AinU+0041 表示英语的大写字母 AU+4E25 表示汉字

具体的符号对应表,可以查询:

  • unicode.org:http://www.unicode.org
  • 汉字对应表:ttp://www.chi2ko.com/tool/CJK.htm

曾有人这样说:

Unicode 支持的字符上限是 65536 个,Unicode 字符必须占两个字节。

但这是一种误解,记住,Unicode 只是一个用来映射字符和数字的标准。它对支持字符的数量没有限制,也不要求字符必须占两个、三个或者其它任意数量的字节,所以它可以无穷大。

3)UTF-8

Unicode 虽然统一了全世界字符的编码,但没有规定如何存储。如果统一规定的话,每个符号就要用 3 个或 4 个字节表示,因为 2 个字节只能表示 65536 个,根本表示不全。

那怎么办呢?

UTF(Unicode Transformation Formats,Unicode 的编码方式)来了!最常见的就是 UTF-8 和 UTF-16。

在 UTF-8 中,0-127 号的字符用 1 个字节来表示,使用和 ASCII 相同的编码。只有 128 号及以上的字符才用 2 个、3 个或者 4 个字节来表示。

如果只有一个字节,那么最高的比特位为 0;如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。

具体的表现形式为:

  • 0xxxxxxx:一个字节;
  • 110xxxxx 10xxxxxx:两个字节编码形式(开始两个 1);
  • 1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式(开始三个 1);
  • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式(开始四个 1)。

也就是说,UTF-8 是一种可变长度的编码方式——这是它的优势也是劣势。

怎么讲呢?优势就是它包罗万象,劣势就是浪费空间。举例来说吧,UTF-8 采用了 3 个字节(256*256*256=16777216)来编码常用的汉字,但常用的汉字没有这么多,这对于计算机来说,就是一种严重的资源浪费。

4)GB2312

基于这样的考虑,中国国家标准总局于 1980 年发布了 GB2312 编码,即中华人民共和国国家标准简体中文字符集。GB2312 标准共收录 6763 个汉字(2 个字节就够用了),其中一级汉字 3755 个,二级汉字 3008 个;同时收录了包括拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母在内的 682 个字符。

GB2312 的出现,基本满足了汉字的计算机处理需求。对于人名、古汉语等方面出现的罕用字和繁体字,GB2312 不能处理,就有了 GBK(K 为“扩展”的汉语拼音(kuòzhǎn)第一个声母)。

中文乱码是如何出现的?

Q:来一串出现中文乱码的 demo,中文为沉默王二

GPT4:下面是一个可能导致中文乱码的示例。首先使用 GBK 编码将中文字符串 “沉默王二” 转换为字节数组,然后使用 UTF-8 编码将字节数组转回字符串。这将导致字符串在解码时出现乱码。

public class EncodingDemo {
    public static void main(String[] args) {
        String originalStr = "沉默王二";
        String encodedStr = "";

        try {
            byte[] bytes = originalStr.getBytes("GBK");
            encodedStr = new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        System.out.println("转码前: " + originalStr);
        System.out.println("转码后: " + encodedStr);
    }
}

程序会输出什么呢?

转码前: 沉默王二
转码后: ��Ĭ����

嘿嘿,乱码来了!在 Unicode 中,� 是一个特殊的符号,它用来表示无法显示,它的十六进制是 0xEF 0xBF 0xBD。那么两个 �� 就是 0xEF 0xBF 0xBD 0xEF 0xBF 0xBD,如果用 GBK 进行解码的话,就是大名鼎鼎的“锟斤拷”。

可以通过代码来验证一下:

// 输出 efbfbdefbfbd
char[] kuijinkao = HexUtil.encodeHex("��", StandardCharsets.UTF_8);
System.out.println(kuijinkao);
// 借助 hutool 转成二进制
byte[] testBytes = HexUtil.decodeHex(kuijinkao);
// 使用 GBK 解码
String testResult = new String(testBytes, Charset.forName("GBK"));
// 输出锟斤拷
System.out.println(testResult);

来看一下输出结果:

efbfbdefbfbd
锟斤拷

所以,以后再见到锟斤拷,第一时间想到 UTF-8 和 GBK 的转换问题准没错。

如何解决中文乱码呢?

Q:如何解决中文乱码呢?

GPT4:解决中文乱码问题需要确保在编码和解码过程中使用相同的字符编码。这是一个修改过的示例,展示了如何避免中文乱码问题:

String originalStr = "沉默王二";

byte[] bytes = originalStr.getBytes(StandardCharsets.UTF_8);
String encodedStr = new String(bytes, StandardCharsets.UTF_8);

System.out.println("正确转码前: " + originalStr);
System.out.println("正确转码后: " + encodedStr);

输出结果:

正确转码前: 沉默王二
正确转码后: 沉默王二

除此之外,以下是一些避免乱码的实践:

  • 使用统一的字符编码,如 UTF-8。它包含了所有 Unicode 字符,并且广泛支持。确保在所有平台和系统上使用相同的编码。
  • 在处理文本文件时,始终明确指定字符编码。例如,在 Java 中使用 InputStreamReader、OutputStreamWriter 时,指定编码参数。
  • 在 HTML、XML 等文档中,指定字符编码。例如,在 HTML 页面中添加 <meta charset="UTF-8">
  • 对于数据库,确保使用正确的字符集。在创建数据库和表时,明确指定字符集,如 utf8mb4。

当与第三方服务通信时,确保双方使用相同的字符编码。在处理 API 请求和响应时,检查字符编码是否匹配。

Q:针对支付宝这种生产环境事故,如何快速定位并解决问题呢?

GPT4:

1、收集信息:了解问题的具体表现,例如哪些页面或功能受到影响,问题的严重程度,以及用户反馈。这将有助于快速定位问题范围。

2、检查日志:查看服务器日志和应用程序日志,检查是否存在异常信息或错误。日志信息有助于识别问题发生的时间和具体原因。

3、复现问题:在测试环境中尝试复现问题,以便更深入地了解问题细节。如果无法复现问题,可能需要进一步收集生产环境的详细信息。

4、定位问题:根据收集到的信息,确定问题可能发生的代码或系统部分。检查相关代码,特别是涉及字符编码、数据传输、数据库操作的部分。

5、解决问题:修复问题代码,确保字符编码在整个系统中保持一致。进行单元测试和集成测试,验证问题是否已解决。

6、部署修复:将修复后的代码部署到生产环境。为了避免影响正常服务,可以考虑先在一个小规模的生产环境中进行验证,然后逐步扩大部署范围。

7、监控:在修复后持续关注系统运行状况,确保问题已得到解决。收集用户反馈,确认用户满意度。

8、总结经验:针对此次问题,总结经验教训,分析问题产生的根本原因,优化开发和测试流程,避免类似问题再次发生。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mesh自组网技术及应用

前言&#xff1a; Mesh自组网随着无线技术发展&#xff0c;在消费领域最近比较有热度。当然应用的场景不限于普通消费领域&#xff0c;在工业、军事领域被也是越来越重要。 一、什么是无线Mesh技术 1.1 无线自组网概念 无线Mesh是一种智能、自组织、多跳、移动、对等、去中心…

滑动验证组件-微信小程序

微信小程序-滑动验证组件&#xff0c;直接引用就可以了&#xff0c;效果如下&#xff1a; 组件参数&#xff1a; 1.enable-close&#xff1a;是否允许关闭&#xff0c;默认true 2.bind:onsuccess&#xff1a;验证后回调方法 引用方式&#xff1a; <verification wx:if&qu…

11.Docker 之分布式仓库 Harbor

Docker 之分布式仓库 Harbor Docker 之分布式仓库 Harbor1. Harbor 组成2. 安装 Harbor Docker 之分布式仓库 Harbor Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器&#xff0c;由 VMware 开源&#xff0c;其通过添加一些企业必需的功能特性&#xff0c;例…

(一)趣学设计模式 之 单例模式!

目录 一、啥是单例模式&#xff1f;二、为什么要用单例模式&#xff1f;三、单例模式怎么实现&#xff1f;1. 饿汉式&#xff1a;先下手为强&#xff01; &#x1f608;2. 懒汉式&#xff1a;用的时候再创建&#xff01; &#x1f634;3. 枚举&#xff1a;最简单最安全的单例&a…

Chrome 浏览器(版本号49之后)‌解决跨域问题

谷歌浏览器解决跨域问题 如何查看 Chrome 浏览器版本号 打开 Chrome 浏览器点击右上角的三个点&#xff0c;打开“设置”页面 点击“关于Chrome” 查看版本号 解决跨域操作&#xff1a;windows系统为例 方法一&#xff1a;命令行启动方式&#xff08;最简单&#xff09; …

python中的JSON数据格式

文章目录 什么是json主要功能Python数据和Json数据的相互转化 什么是json JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据。JSON本质上是一个带有特定格式的字符串。 主要功能 json就是一种在各个编程语言中流通的数据格式&#xff0c;负责不同编…

汽车智能制造企业数字化转型SAP解决方案总结

一、项目实施概述 项目阶段划分&#xff1a; 蓝图设计阶段主数据管理方案各模块蓝图设计方案下一阶段工作计划 关键里程碑&#xff1a; 2022年6月6日&#xff1a;项目启动会2022年12月1日&#xff1a;系统上线 二、总体目标 通过SAP实施&#xff0c;构建研产供销协同、业财一…

JavaWeb-在idea中配置Servlet项目

文章目录 在idea中进行Servlet项目的配置(较新的idea版本)创建一个空的JavaSE项目(Project)创建一个普通的JavaSE板块(module)添加Web项目的配置定义一个对象模拟实现接口在web.xml中配置路径映射配置项目到Tomcat服务器启动Tomcat服务器进行测试 在idea中进行Servlet项目的配置…

【深度学习神经网络学习笔记(二)】神经网络基础

神经网络基础 神经网络基础前言1、Logistic 回归2、逻辑回归损失函数3、梯度下降算法4、导数5、导数计算图6、链式法则7、逻辑回归的梯度下降 神经网络基础 前言 Logistic 回归是一种广泛应用于统计学和机器学习领域的广义线性回归模型&#xff0c;主要用于解决二分类问题。尽…

力扣hot100 —— 电话号码字母组合; 子集 (非回溯做法)简单易懂

由于博主对回溯也不是很熟悉&#xff0c;这里提出一种简单易懂的解法&#xff08;有点暴力&#xff09; 解题思路&#xff1a; 每个数字对应有自己的字母串&#xff1b; 首先遍历将每个字母存入也就是 res{{a},{b},{c}} 然后遍历后续数子对应的字母&#xff0c;让每个字母与…

React 源码揭秘 | 更新队列

前面几篇遇到updateQueue的时候&#xff0c;我们把它先简单的当成了一个队列处理&#xff0c;这篇我们来详细讨论一下这个更新队列。 有关updateQueue中的部分&#xff0c;可以见源码 UpdateQueue实现 Update对象 我们先来看一下UpdateQueue中的内容&#xff0c;Update对象&…

解锁养生密码,拥抱健康生活

在快节奏的现代生活中&#xff0c;养生不再是一种选择&#xff0c;而是我们保持活力、提升生活质量的关键。它不是什么高深莫测的学问&#xff0c;而是一系列融入日常的简单习惯&#xff0c;每一个习惯都在为我们的健康加分。 早晨&#xff0c;当第一缕阳光洒进窗户&#xff0c…

muduo网络库2

Muduo网络库&#xff1a;底层实质上为Linux的epoll pthread线程池&#xff0c;且依赖boost库。 muduo的网络设计核心为一个线程一个事件循环&#xff0c;有一个main Reactor负载accept连接&#xff0c;然后把连接分发到某个sub Reactor(采用轮询的方式来选择sub Reactor)&…

【大语言模型】【整合版】DeepSeek 模型提示词学习笔记(散装的可以看我之前的学习笔记,这里只是归纳与总结了一下思路,内容和之前发的差不多)

以下是个人笔记的正文内容: 原文在FlowUs知识库上&#xff0c;如下截图。里面内容和这里一样&#xff0c;知识排版好看一点 一、什么是 DeepSeek 1. DeepSeek 简介 DeepSeek 是一家专注于通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与…

AWQ和GPTQ量化的区别

一、前言 本地化部署deepseek时发现&#xff0c;如果是量化版的deepseek&#xff0c;会节约很多的内容&#xff0c;然后一般有两种量化技术&#xff0c;那么这两种量化技术有什么区别呢&#xff1f; 二、量化技术对比 在模型量化领域&#xff0c;AWQ 和 GPTQ 是两种不同的量…

ARM Cortex-M3 技术解析:核寄存器R1-R15介绍及使用

ARM Cortex-M3 技术解析&#xff1a;核寄存器R1-R15介绍及使用 作为嵌入式开发领域的经典处理器内核&#xff0c;ARM Cortex-M3&#xff08;CM3&#xff09;凭借其高效能、低功耗和丰富特性&#xff0c;在工业控制、物联网、消费电子等领域广泛应用。而内核寄存器是我们调试代…

ROS ur10机械臂添加140夹爪全流程记录

ROS ur10机械臂添加140夹爪 系统版本&#xff1a;Ubuntu20.04 Ros版本&#xff1a;noetic Moveit版本&#xff1a;moveit-noetic 参考博客&#xff1a; ur3robotiq ft sensorrobotiq 2f 140配置rviz仿真环境_有末端力传感器的仿真环境-CSDN博客 UR5机械臂仿真实例&#xf…

Web自动化之Selenium添加网站Cookies实现免登录

在使用Selenium进行Web自动化时&#xff0c;添加网站Cookies是实现免登录的一种高效方法。通过模拟浏览器行为&#xff0c;我们可以将已登录状态的Cookies存储起来&#xff0c;并在下次自动化测试或爬虫任务中直接加载这些Cookies&#xff0c;从而跳过登录步骤。 Cookies简介 …

【落羽的落羽 数据结构篇】树、二叉树

文章目录 一、树1. 树的概念和结构2. 树的相关术语 二、二叉树1. 概念与结构2. 满二叉树3. 完全二叉树4. 二叉树的性质5. 二叉树的存储结构 一、树 1. 树的概念和结构 之前我们学习了线性表&#xff0c;今天我们再来接触一种全新的数据结构——树。 树是一种非线性的数据结构…