
正文
Java 编码那些事(一)
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
编码
做Web的同学,最开始一定遇到过乱码问题,工作这么久,一定听说过
Unicode
,
GB2312
等编码。典型的记事本选择的四种选项:
ANSI,Unicode,Unicode big endian,UTF-8
,有没有疑惑,这都是些什么鬼???
什么是编码?
众所周知,计算机存储都是0和1,那计算机是如何区分开汉字,字母呢?后来人们就规定了一个编码表,这个表就相当于一个
字典
,比如我们通俗约定1100001就表示
A
,1100002表示
B
做计算机显示的时候,发现一个字符对象存储的值是
1100001
那就显示
A
就行了。像这样,
由信息的一种形式转换为另外一种形式的过程,称为编码。
而编码表便是编码过程的一种规则。
ASCII
ASCII(American Standard Code for Information Interchange)
是最出名也是最基本的编码表,最开始计算机发明的时候,计算机的使用一般都是一些特殊字符加上26个字母,因此美国人定制了
ASCII
表用来显示通用的26个字符加上一些特殊字母,
ASCII
码只占用一个1字节。
ANSI
最开始
ASCII
编码是够用的,但是随着计算机的发展,越来越多的国家陆续用上了计算机,这个时候,母语非英语的国家就开始不满意了,
ASCII
只能表示26个英文字母,那法语(
é
),汉语(中国),德语(
Ä ä
)等也要在计算机中表示,于是最开始,每个国家都自己定义了一套关于自己的编码规则,其中比较出名的有:
-
西欧 ISO 8859-1
-
中国国标 GB 2312
-
台湾同胞的繁体 Big 5
-
日本 Shift_ JIS
这些都是编码都是在原有的
ASCII
基础上扩展而来,统称为
ANSI
编码。但是最大的缺点就是
互不兼容
,也就是每个编码都是在没有考虑其他国家的定义的基础上扩展的。一边来说,在解码/编码过程中,都是指定具体的编码,比如
GBK2312
,
ISO 8859-1
等,
ANSI
只是对上述编码的一种统称。使用
ANSI
来作为一种编码格式的一般只见于
Windows
自带的记事本中。而在
Windows
记事本中,不同语言的操作系统,记事本所指的
ANSI
是不同的,
- 简体中文 GBK
- 日文 Shift_JIS
- 繁体中文 Big 5
- ...
因此,对于
Windows
的记事本,
ANSI
需要看具体的编码。
UNICODE
首先需要明确的是
UNICODE
是将
字符集
和
编码方式
分开的一种方案,在维基百科中又被称做万国码、国际码。由名字便可知道,
Unicode
统一了各个国家的字符并规定了每个符号的编码,在
Unicode
字符集
中,每个字符占用两个字节表示。
ANSI
类的字符集合编码都是一对一的关系,一种字符集对应一种编码。在
Unicode
编码中,
Unicode
编码的实现方式被称为
Unicode转换格式
(
Unicode Transformation Format
,简称为
UTF
):代表性的有以下几种:
-
UTF-8: 前面说得到,
Unicode字符集是以2个字节表示一个字符,但是在有时候只需要ASCII编码即可完整表示所有内容的系统中,使用Unicode会浪费比较多的控件,因此出现了UTF-8编码,UTF-8是一种变长编码。UTF-8在编码Unicode码的时候,会将小位数的字符进行压缩,因此使用UTF-8的表示一个字母的时候,依然只使用一个字节。UTF-8对常用的字符一般3个字节即可表示,最多6个字节。(尽管如此,2003年11月UTF-8被RFC 3629重新规范,只能使用原来Unicode定义的区域,U+0000到U+10FFFF,也就是说最多四个字节:维基百科) -
UTF-16:
UTF-16使用16位作为一个字长单位,使用UTF-16要么是两个字节表示一个字符,要么是4个字节。不过值得注意的是不同的操作系统读取直接的顺序不同,就好像古人写字是从右往左写一样,这里顺序,称为 字节序 ,比如1122,有些系统读出来是1122,而有些系统读出来是2211,所以UTF-16又分大端( utf16-big endian )和小端( utf16-little endian )表示。
关于为什么UTF-8 没有字节序的问题,感兴趣的同学可以看看为什么 UTF-8 不存在字节序的问题? - 孙笑凡的回答 - 知乎
说到这里,大概就能分清
UNICODE
,
ANSI
,
UTF-8
,
GBK
编码了,但是可能有的同学比较疑惑的是
Windows
自带的笔记本为什么会有个
Unicode
编码选项??这算是
Windows
混用概念问题,在
Windows
自带笔记本下的Unicode表示的是
“Unicode”
(对应
UTF-16 LE
)、
“Unicode big endian”
(对应
UTF-16 BE
)
URLEncoding
URLEncoding
又称为
百分号编码
,其主要作用在于解决在
使用url中混合其他编码的时候所带来的语法冲突
,比如
?
在URL中,表示参数分割,但是如果想要在参数中传递
?
就必须通过特殊的转换,而
URLEncoding
则正是用来将这些特殊符号转换为其他不会有歧义的统一编码。
其主要编码原理在于:将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上
%
,编码成
%XY
格式
部分特殊字符转换规则如下:
| 空格 | ! | # | $ | % | + | @ | : | = | ? |
|---|---|---|---|---|---|---|---|---|---|
| %20 | %21 | %23 | %24 | %25 | %2B | %40 | %3A | %3D | %3F |
一般当参数会混合在
URL
中,都会先将参数进行
URL
编码再进行传递。比如
Get
请求,或者
HTTP
中
MIME
类型为
application/x-www-form-urlencoded
的请求
~~
微信搜索:StackTrace,一起学习,一起讨论,一起进步






