Java 字符编码
编码:数据存储进计算机中需要转换为二进制存储,这个过程就是编码。
解码:计算机读取数据并展示在页面上,需要将二进制转换为人类语言的过程,叫做解码。
乱码:如果编码和解码时使用的码表不一样,就会产生乱码。
码表:就是将人类可以看懂的数据格式转换成计算机能够认识的二进制形式的参考表,称为码表。
ASCII
American Standard Code for Information Interchange,美国信息交换标准代码。
计算机发明之初,基本只考虑了美国的需求,而美国大概只需要 128 个字符,用 7 位刚好可以表示,计算机存储的最小单位是 byte,ASCII 中最高位设置为 0,剩下的 7 位表示字符,ASCII 码规定了 0 ~ 127 对应的字符。
数字 32~126 表示的字符都是可打印字符。
0~31 和 127 表示一些不可打印的字符。
数字 | 缩写/字符 | 解释 | 转义字符 |
---|---|---|---|
0 | NUL(null) | 空字符 | \0 |
8 | BS(backspace) | 退格 | \b |
9 | HT(horizontal tab) | 水平制表符 | \t |
10 | LF(NL line feed,new line) | 换行键 | \n |
13 | CR(carriage return) | 回车键 | \r |
27 | ESC | 换码 | |
127 | DEL(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();}}}
}
相关文章:

Java 字符编码
编码:数据存储进计算机中需要转换为二进制存储,这个过程就是编码。 解码:计算机读取数据并展示在页面上,需要将二进制转换为人类语言的过程,叫做解码。 乱码:如果编码和解码时使用的码表不一样,…...

ubuntu-9-安装chrony时间同步
使用chrony搭建时间同步服务器 [Linux系列]Chrony时间同步服务器 配置chrony服务,实现服务器时间自动同步 linux上内网环境配置NTP时间同步详解 经验体会:解决Ubuntu 18.04Windows双系统时间不同步的问题 1 时间同步 我们知道一台电脑主机,…...

CMMI流程规范—服务与维护
服务与维护(Service and Maintenance, SM)是指产品销售之后的客户服务和产品维护。客户服务和产品维护的宗旨就是提高客户对产品以及对开发方的满意度。服务与维护过程域是SPP模型的重要组成部分。本规范阐述了服务与维护过程域的两个主要规程࿱…...

【蓝桥杯集训12】DFS(3 / 5)
目录 842. 排列数字 - DFS按位置枚举 843. n-皇后问题 - DFS按行枚举 165. 小猫爬山 - DFS枚举小猫 1209. 带分数 - DFS 3502. 不同路径数 - 842. 排列数字 - DFS按位置枚举 活动 - AcWing 题目: 给你一个整数n 要求将1~n的所有排列情况列出 比如:…...

Elasticsearch:构建自动补全功能 - Autocomplete
什么是自动补全(autocomplete)功能呢?我们举一个很常见的例子。 每当你去谷歌并开始打字时,就会出现一个下拉列表,其中列出了建议。 这些建议与查询相关并帮助用户完成查询。 Autocomplete 正如维基百科所说的…...

One UI 5.1 更新来了
之前一直在关注One UI 5.0里提到的视频通话背景功能模块,结果5.0版本推送的时候没有引入,有先行者计划博主说是5.1里肯定会有的;前一两天One UI 5.1更新来了,然而该功能还是没有引入,表示很遗憾;本次更新新…...

Python学习笔记11:文件
文件 打开文件 函数open的参数mode的最常见取值 值描述‘r’读取模式(默认值)‘w’写入模式‘x’独占写入模式‘a’附加模式‘b’二进制模式(与其他模式结合使用)‘t’文本模式(默认值,与其他模式结合使…...

django-filter的使用
django-filter是一个通用的、可重用的应用程序,它可以减轻视图代码的编写工作量。具体来说,它允许用户根据模型的字段筛选查询集,并显示表单让他们这样做。 安装 pip install django-filter快速开始 在settings.py中添加如下配置: INSTAL…...

时序预测 | MATLAB实现IWOA-BiLSTM和BiLSTM时间序列预测(改进的鲸鱼算法优化双向长短期记忆神经网络)
时序预测 | MATLAB实现IWOA-BiLSTM和BiLSTM时间序列预测(改进的鲸鱼算法优化双向长短期记忆神经网络) 目录时序预测 | MATLAB实现IWOA-BiLSTM和BiLSTM时间序列预测(改进的鲸鱼算法优化双向长短期记忆神经网络)预测效果基本介绍程序设计参考资料预测效果 基本介绍 MATLAB实现IWO…...

【C++】string的成员函数、成员常量和非成员函数
目录 string 1. string的成员函数 1.1 构造、析构和赋值运算符重载 1.1.1 构造函数 1.1.2 析构函数 1.1.3 赋值运算符重载 1.2 迭代器 1.3 容量 1.4 元素访问 1.4.1 遍历方法 1.5 修改器 1.6 字符串操作 2. string的成员常量 3. string的非成员函数 string 以下…...

网络互连模型:OSI 七层模型
OSI 七层模型 七层模型,亦称 OSI(Open System Interconnection)。OSI 七层参考模型是国际标准化组织(ISO)制定的一个用于计算机或通信系统间网络互联的标准体系,一般称为 OSI 参考模型或七层模型。OSI 七层…...

18跨越语言:不同语言间进行RPC通信
在最开始介绍gRPC时我们讲到,gRPC具有灵活的兼容性,可以支持很多种编程语言,下面我们就使用在后端领域最常用的两种编程语言Go和Java,来体验一下gRPC在不同语言的项目间是如何进行通信的。 逻辑架构 由上图我们可以看出,Go语言设计gRPC的服务端,Java语言设计gRPC的客户端…...

解压缩工具:Bandizip 中文
bandizip是一款可靠和快速的压缩软件,它可以解压RAR、7Z、ZIP、ISO等数十种格式,也可以压缩7Z、ZIP、ISO等好几种常用格式,在压缩文件方面毫不逊色于winrar,适用于多核心压缩、快速拖放、高速压缩等功能,采用了先进快速…...

JAVA知识点全面总结2:面向对象
二.面向对象 1.面向对象有哪些重要的关键字?作用是什么? 2.理解多态的使用? 3.接口与抽象类的相同点和不同点? 4.equals和toString的判断? 5.新建对象的流程是什么?new一个对象? 6.深拷贝…...

DNS作用及工作原理
文章目录1. DNS作用2 DNS 三个组成部分:2.1 客户端2.2Local DNS2.3 权威域 DNS 服务器3 工作过程1. DNS作用 DNS 分为 Client 和 Server,Client 扮演发问的角色,也就是问 Server 一个 Domain Name,而 Server 必须要回答此 Domain…...

Android 9.0 wifi的随机mac地址修改为固定不变
1.前言 在9.0的系统rom产品定制化开发中,在系统默认的wifi的mac地址是会在联网前后会变化,因为默认是随机显示mac地址,所以会在连上wifi后mac地址会变动但是如果根据mac地址来升级 会引起一系列问题,为了避免这些问题 所以就要求固定mac地址,这就需要看wifi模块怎么改变ma…...

Apinto 网关 V0.11.1 版本发布,多协议互转,新增编码转换器,接入 Prometheus
Eolink 旗下 Apinto 开源网关再次更新啦~ 一起来看看是否有你期待的功能! 1、协议转换功能上线 之前发布的 Apinto v0.10.0 已经支持了多协议的基本功能,实现多协议支持的一次验证。本次最新版本可以支持 HTTP 与 gRPC、HTTP 与 Dubbo2 之间的协议转换。…...

Android 12.0 根据app包名授予app监听系统通知权限
1.概述 在12.0的系统rom产品定制化开发中,在一些产品rom定制化开发中,系统内置的第三方app需要开启系统通知权限,然后可以在app中,监听系统所有通知,来做个通知中心的功能,所以需要授权 获取系统通知的权限,然后来顺利的监听系统通知。来做系统通知的功能 2.根据app包名…...

mysql视图和存储过程
视图视图就是将一条sql查询语句封装起来,之后使用sql时,只需要查询视图即可,查询视图时会将这条sql语句再次执行一遍。视图不保存数据,数据还是在表中。SELECT 语句所查询的表称为视图的基表,而查询的结果集称为虚拟表…...

uniapp 实现人脸认证
前言 对于前端来说,需要后端提供一个人脸识别接口,前端传入图片,接口识别并返回结果,如此看来,其实前端只需实现图片传入即可,但是其实不然,在传入图片时,需要进行以下几点操作&…...

自学大数据第三天~终于轮到hadoop了
前面那几天是在找大数据的门,其实也是在搞一些linux的基本命令,现在终于轮到hadoop了 Hadoop hadoop的安装方式 单机模式: 就如字面意思,在一台机器上运行,存储是采用本地文件系统,没有采用分布式文件系统~就如我们一开始入门的时候都是从本地开始的; 伪分布式模式 存储采用…...

Unity 入门精要00---Unity提供的基础变量和宏以及一些基础知识
头文件引入: XXPROGRAM ... #include "UnityCG.cginc"; ... ENDXX 常用的结构体(在UnityCg.cginc文件中):在顶点着色器输入和输出时十分好用 。 关于如何使用这些结构体,可在Unity安装文件目录/Editor…...

Kubernetes的网络架构及其安全风险
本博客地址:https://security.blog.csdn.net/article/details/129137821 一、常见的Kubernetes网络架构 如图所示: 说明: 1、集群由多个节点组成。 2、每个节点上运行若干个Pod。 3、每个节点上会创建一个CNI网桥(默认设备名称…...

Blob分析+特征+(差分)
Blob分析特征0 前言1 概念2 方法2.1 图像采集2.2 图像分割2.3 特征提取3 主要应用场景:0 前言 在缺陷检测领域,halcon通常有6种处理方法,包括Blob分析特征、Blob分析特征差分、频域空间域、光度立体法、特征训练、测量拟合,本篇博…...

Flink 提交模式
Flink的部署方式有很多,支持Local,Standalone,Yarn,Docker,Kubernetes模式等。而根据Flink job的提交模式,又可以分为三种模式: 模式1:Application Mode Flink提交的程序,被当做集群内部Application,不再需要Client端做繁重的准备工作。(例如执行main函数,生成JobG…...

网络总结知识点(网络工程师必备)三
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放,树高千尺,落叶归根人生不易,人间真情 目录 前言 51.什么是ARP代理?...

测开:前端基础-css
一、CSS介绍和引用 1.1 css概述 层叠样式表,是一种样式表语言,用来描述HTML和XML文档的呈现。 CSS 用于简化HTML标签,把关于样式部分的内容提取出来,进行单独的控制,使结构与样式分离开发。 CSS 是以HTML为基础&…...

Java学习记录之JDBC
JDBC JDBC 是 Java Database Connectivity 的缩写,是允许Java 程序访问并操作关系型数据库数据的一套 应用程序接口。本身就是一种规范,它提供的接口有一套完整的,可移植的访问底层数据库的程序。 JDBC 的架构 JDBC API支持两层和三层处理…...

矩阵翻硬币
题目描述 小明先把硬币摆成了一个 n 行 m 列的矩阵。 随后,小明对每一个硬币分别进行一次 Q 操作。 对第 x 行第 y 列的硬币进行 Q 操作的定义:将所有第 ix 行,第 jy 列的硬币进行翻转。...

【C语言跬步】——指针数组和数组指针(指针进阶)
一.指针数组和数组指针的区别 1.指针数组是数组,是一种存放指针的数组; 例如: int* arr[10]; 2.数组指针是指针,是一种指向数组的指针,存放的是数组的地址; 例如: int arr[5]; int (p)[5]&a…...