Java 字符编码

news2025/2/26 9:55:31

编码:数据存储进计算机中需要转换为二进制存储,这个过程就是编码。
解码:计算机读取数据并展示在页面上,需要将二进制转换为人类语言的过程,叫做解码。
乱码:如果编码和解码时使用的码表不一样,就会产生乱码。
码表:就是将人类可以看懂的数据格式转换成计算机能够认识的二进制形式的参考表,称为码表。

ASCII

American Standard Code for Information Interchange,美国信息交换标准代码。

计算机发明之初,基本只考虑了美国的需求,而美国大概只需要 128 个字符,用 7 位刚好可以表示,计算机存储的最小单位是 byte,ASCII 中最高位设置为 0,剩下的 7 位表示字符,ASCII 码规定了 0 ~ 127 对应的字符。

数字 32~126 表示的字符都是可打印字符。

image.png

0~31 和 127 表示一些不可打印的字符。

数字缩写/字符解释转义字符
0NUL(null)空字符\0
8BS(backspace)退格\b
9HT(horizontal tab)水平制表符\t
10LF(NL line feed,new line)换行键\n
13CR(carriage return)回车键\r
27ESC换码
127DEL(delete)删除

ASCII 码对美国够用,但对其他国家是不够的。

各国的计算机厂商发明了各自的编码方式以表示自己国家的字符,为了保持与 ASCII 码的兼容性,一般都是将最高位设置为 1。

就是说,当最高位为 0 时,表示 ASCII 码,当为 1 时就是各个国家自己的字符。

ISO 8859-1

ISO 8859-1 又称 Latin-1,同样使用一个字节表示一个字符。

其中 0~127 与 ASCII 一样,128~255 规定了不同的含义。

Windows-1252

基本上可以认为,ISO8859-1 已被 Windows-1252 取代,在很多应用程序中,即使文件声明它采用的是 ISO 8859-1 编码,解析的时候依然被当作 Windows-1252 编码。

GBK

GBK 使用固定的两个字节表示字符,高位字节范围是 0x81~0xFE ,低位字节范围是 0x40~0x7E 和 0x80~0xFE。

需要注意的是,低位字节是从 0x40(即64)开始的,因此低位字节的最高位可能为 0,如何判断它是汉字还是 ASCII 字符呢?因为汉字是用固定两个字节表示的,当第一个字节的最高位为 1 时,直接将下一个字节一起解析,然后跳到第三个字节继续解析。

Unicode

Unicode 给世界上所有字符都分配了一个唯一的数字编号,编号范围从 0x000000~0x10FFFF。

每个字符都有一个 Unicode 编号,这个编号一般写成十六进制,在前面加 U+,比如“马”的 Unicode 编码是 U+9A6C。

Unicode 给字符分配了统一的数字编号,但它并没有规定这个编号怎么对应到二进制表示。

编号怎么对应到二进制表示?主要方案有 UTF-32、UTF-16 和 UTF-8 。

UTF-32

字符 Unicode 编号的整数二进制形式,4个字节,根据字节排序的不同(大端和小端)分为 UTF-32BE 和 UTF-32LE。

UTF-16

UTF-16 使用变长字节表示。对于编号在 U+0000 ~ U+FFFF的字符(常用字符),直接用 2 个字节表示,U+D800~U+DBFF的编号其实是没有定义的。

编号在 U+10000 ~ U+10FFFF的字符(增补字符集),需要使用 4 个字节表示,前两个字节叫高代理项,范围是U+D800~U+DBFF;后两个字节叫低代理项,范围是U+DC00~U+DFFF。

区分是2个字节还是4个字节表示一个字符就看前两个字节的编号范围,如果是U+D800~U+DBFF,就是4个字节,否则就是2个字节。

UTF-16也有和UTF-32一样的字节序问题,如果高位存放在前面就叫大端(BE),编码就叫UTF-16BE,否则就叫小端,编码就叫UTF-16LE。

UTF-8

UTF-8 使用变长字节表示,字符使用的字节个数与其 Unicode 编号的大小有关,编号小的使用的字节就少,字节个数为 1~4 不等。

编号范围二进制格式
0x00 ~ 0x7F(0 ~ 127)0xxx xxxx
0x80 ~ 0x7FF(128 ~ 2047)110x xxxx 10xx xxxx
0x800 ~ 0xFFFF(2048 ~ 65535)1110 xxxx 10xx xxxx 10xx xxxx
0x10000 ~ 0x10FFFF(65536以上)1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx

上表中,x 表示可以用的二进制位,而每个字节开头的1或0是固定的。

UTF-8 将字符看作整数,转化为二进制形式(去掉高位的 0),然后将二进制位从右向左依次填入对应的二进制格式 x 中,填充完后,如果对应的二进制格式还有没填的 x,则设为 0。

/*

如 '马' 的 Unicode 编号是 0x9A6C,整数编号是 39532,二进制 1001 101001 101100

对应的 UTF-8 二进制格式是:1110 xxxx 10xx xxxx 10xx xxxx

将二进制 1001 101001 101100 从右到左依次填入二进制格式中

结果就是其 UTF-8 编码:1110 1001 1010 1001 1010 1100

*/

UTF-8 是兼容 ASCII 的,对大部分中文字符而言,需要使用三个字节表示。

Java 中的编码

Java 源码可以使用任何形式的编码,默认使用的是电脑系统自带的编码。

源码编译后生成 .class 文件,.class 文件中字符编码为 modified UTF-8,它类似于 UTF-8,但是二者不同。

JVM 运行的时候,将 modified UTF-8 解码成 UTF-16,UTF-16 编码是字符 char 在内存中的编码形式。

总结就是源代码从【某种编码方式】编码成 modified UTF-8 再到 modified UTF-8 解码成执行期的 UTF-16(便于统一处理)。

编码转换

不同编码格式之间可以借助 Unicode 编号进行编码转换。可以认为,每种编码都有一个映射表,存储 Unicode 编号和其特有的字符编码之间的对应关系。

编码转换的具体过程可以是:一个字符从 A 编码转到 B 编码,先找到字符的 A 编码格式,通过 A 编码的映射表找到其 Unicode 编号,然后通过 Unicode 编号再查找 B 编码的映射表,找到字符的 B 编码格式。

乱码问题

解析错误

使用错误的编码进行解析,比如小明采用 Windows-1252 写了个文件,发送给了小红,小红使用 GBK 来解析这个字符,看到的可能就是乱码。

编码转换错误

在错误解析的基础上还进行了编码转换。比如文件实际是 Windows-1252编码,小红用 GBK 解析打开后看到乱码,又转换成了 UTF-8 编码。

乱码恢复

恢复要抓住两个关键信息:一个是原来的二进制编码方式A;另一个是错误解读的编码方式B。

public static void recover(String str)  throws UnsupportedEncodingException {
	String[] charsets = {"windows-1252", "GB18030", "Big5", "UTF-8"};

	for(int i = 0; i< charsets.length; i++){
		for(int j = 0; j < charsets.length; j++){
			if(i != j){
				String s = new String(str.getBytes(charsets[i]), charsets[j]);
				System.out.println("---- 原来编码(A)假设是: " + charsets[j]
						+ ", 被错误解读为了(B): " + charsets[i]);
				System.out.println(s);
				System.out.println();
			}
		}
	}
}

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

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

相关文章

ChatGPT火爆,元宇宙“熄火”?别操之过急,也别敷衍了事

近期&#xff0c;在ChatGPT火爆的同时&#xff0c;元宇宙“遇冷”的消息引起关注。据科技圈流传&#xff0c;大量元宇宙聊天群一夜之间改名为ChatGPT聊天群。ChatGPT火爆出圈导致元宇宙“熄火”&#xff0c;真的是这样吗&#xff1f;ChatGPT与元宇宙二者有怎样的底层逻辑关联&a…

Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号

首先区分一下Linux信号跟进程间通信中的信号量&#xff0c;它们的关系就犹如老婆跟老婆饼一样&#xff0c;没有一毛钱的关系。 信号的概念 信号的概念&#xff1a;信号是进程之间事件异步通知的一种方式&#xff0c;属于软中断。比如&#xff1a;红绿灯是一种信号&#xff0c…

机器学习:基于神经网络对用户评论情感分析预测

机器学习&#xff1a;基于神经网络对用户评论情感分析预测 作者&#xff1a;AOAIYI 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;AOAIYI首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f4…

深入理解RDBMS-学习笔记

1 经典案例 1.1 红包雨 1.2 事务ACID 1.3 红包雨与ACID 1.3.1 原子性 1.3.2 一致性 1.3.3 隔离性 1.3.4 持久化 1.4 红包雨与高并发 1.5 红包雨与高可靠 2 发展历史 2.1 前DBMS时代 2.1.1 人工管理 2.1.2 文件系统 1950s&#xff0c;现代计算机的雏形基本出现。1956年IB…

怎样对一张图像进行直方图均衡化?(或者图像均衡化代码?)

怎样对一张图像进行直方图均衡化&#xff1f;&#xff08;或者图像均衡化代码&#xff1f;&#xff09; 图像增强概述 图像增强是有目的地强调图像的整体或局部特性&#xff0c;将原来不清晰的图像变得清晰或强调某些感兴趣的特征&#xff0c;扩大图像中不同物体特征之间的差…

认识异或运算

1.什么是异或运算 异或运算是位运算的一种&#xff0c;符号为&#xff1a;^ 运算规则为&#xff1a;相同为0&#xff0c;不同为1 例如 性质&#xff1a; N ^ 0 N N ^ N 0 A ^ B B ^ A (A ^ B) ^ C A ^ (B ^ C)N ^ 0 N public class XorOperation {public static void …

【算法基础】排序 插入、归并、堆、快速 升序+降序

目录 1.排序 1.1 插入排序 1.2 归并排序 1.3 推排序 1.4 快速排序 1.排序 1.1 插入排序 时间复杂度&#xff1a;O(n)~O(n*n) 空间复杂度&#xff1a;O(1) 稳定 步骤&#xff1a; 1.设第一个元素为有序列。 2.取有序列后面的一个元素。 3.将该元素插入到有序列中的正确位…

【C语言学习笔记】:一维数组指针,二维数组指针

数组&#xff08;Array&#xff09;是一系列具有相同类型的数据的集合&#xff0c;每一份数据叫做一个数组元素&#xff08;Element&#xff09;。数组中的所有元素在内存中是连续排列的&#xff0c;整个数组占用的是一块内存。以int arr[] { 99, 15, 100, 888, 252 };为例&am…

Linux | 调试器GDB的详细教程【纯命令行调试】

文章目录一、前言二、调试版本与发布版本1、见见gdb2、程序员与测试人员3、为什么Release不能调试但DeBug可以调试❓三、使用gdb调试代码1、指令集汇总2、命令演示⌨ 行号显示⌨ 断点设置⌨ 查看断点信息⌨ 删除断点⌨ 开启 / 禁用断点⌨ 运行 / 调试⌨ 逐过程和逐语句⌨ 打印 …

C/C++开发,无可避免的多线程(篇二).thread与其支持库

一、原子类型与原子操作 1.1 原子类型与操作介绍 在前一篇博文中&#xff0c;多线程交互示例代码中&#xff0c;给出了一个原子类型定义&#xff1a; // 原子数据类型 atomic_llong total {0}; 那么什么事原子数据类型呢&#xff0c;和c的基础数据类型有什么不同呢&#xff1a…

实验一 Python编程基础

目录 一、实验目标 二、实验内容 1.绘制如下图形 &#xff0c;一个正方形&#xff0c;内有三个红点&#xff0c;中间红点在正方形中心。 2.使用turtle库绘制如下图形&#xff1a; 3.绘制奥运五环图 4.回文问题 5.身份证性别判别 6.数据压缩 7.验证哥德巴赫猜想 8.使…

JVM常用指令

JVM常用指令1.准备工作2.jps3. jconsole4.jstat5.jstack6.jmap7.jvisualvm工具8.自动dump内存信息1.准备工作 在idea中编写代码 public class JVMTest {Testpublic void test() throws InterruptedException {while (true) {Thread.sleep(1000);System.out.println(123);}} }…

Unity 入门精要01---标准光照模型

本节基础知识结构 基础光照部分 环境光 在标准光照模型中&#xff0c;我们会环境光来代替间接光照 Cambient g amient 我们可以在Windows->Rendering->Lighting->Enviroment进行修改Ambient 的Color 自发光 直接在最后片元着色器输出颜色之前把材质的自发光颜色添…

深圳大学计软《面向对象的程序设计》实验13 运算符重载

A. 三维坐标点的平移&#xff08;运算符重载&#xff09; 题目描述 定义一个三维点Point类&#xff0c;利用友元函数重载"“和”–"运算符&#xff0c;并区分这两种运算符的前置和后置运算。 要求如下&#xff1a; 1.实现Point类&#xff1b; 2.编写main函数&a…

关于2023年造林施工、林业设计资质,新办、年审的最新通知!

一、资质类别省林学会本年度开展认定的资质种类包括&#xff1a;造林绿化类&#xff08;含施工资质、监理资质&#xff09;、林业有害生物防治类&#xff08;含防治资质、监理资质&#xff09;和林业调查规划设计类。二、认定标准资质认定执行以下标准&#xff1a;1.造林绿化施…

边缘计算:万字长文详解高通SNPE inception_v3安卓端DSP推理加速实战

本文是在以下文章的基础上编写&#xff0c;关于SNPE环境部署和服务器端推理可以参考上一篇文章&#xff1a; 边缘计算&#xff1a;万字长文详解高通SNPE inception_v3推理实战_seaside2003的博客-CSDN博客 本文最/关键的是利用SNPE在安卓环境不同的runtimes&#xff08;CPU/G…

高通 Android10/12 4 6dof Camera+2RGBCamera异常处理经验总结

1 背景&#xff1a;此需求apk距离之前更改时间将近9个月&#xff0c;我们这边原来跟驱动那边对接指令和角度 后续没有改过&#xff0c;测试部说apk cameaid提示信息不正确。 2 原因&#xff1a;因为之前用的1.0基线&#xff08;Android 10) 后面由于客户功能需求变更&#xff…

进程信号生命周期详解

信号和信号量半毛钱关系都没有&#xff01; 每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定 义 #define SIGINT 2 查看信号的机制&#xff0c;如默认处理动作man 7 signal SIGINT的默认处理动作是终止进程&#xff0c;SIGQUIT的默认处理…

23届春招结束_分享java岗面试心得

23届春招结束_分享java岗面试心得 从一月10日开始投简历&#xff0c;经历了两个月的面试与学习&#xff0c;成功拿到了12k13薪的国企offer&#xff0c;春招结束了 一、经历秋招&#xff0c;被所谓的金九银十给坑惨了 在秋招的时候&#xff0c;经过网友&#xff08;美团java岗…

九龙证券|利好政策密集发布,机构扎堆看好的高增长公司曝光

新能源轿车销量和保有量快速增长&#xff0c;带来了充电桩商场的微弱需求。 日前&#xff0c;商务部部长王文涛表明&#xff0c;本年将在落实好方针的一起&#xff0c;活跃出台新方针办法&#xff0c;比方辅导当地展开新能源轿车下乡活动&#xff0c;优化充电等使用环境&#x…