乱码或者转码,是开发中经常碰到的问题. 理解了编码到底是怎么回事,解决起来就会轻松很多.
继续提出问题并解决;
1. 位,字节,字符,编码,字符集的概念
2.java中的转码方式
3.常见乱码问题
1. 位,字节,字符,编码,字符集的概念
位(bit): 我们都知道计算机只认识01, 一bit就是这里的一个0或者1.(二进制的01)
字节(byte): 8个bit构成一个byte,可以表示英语字母,数字(这里01是十进制的),还可以表示一些符号.是一个很具体的存储空间.(例如 0x01, 0x45)
字符: 一个或多个字节组合起来代表一个字符.
编码: 字节组合成字符时,需要一定的规则,这个规则就是编码方式.(经常看到说1个汉字=2个字节,其实是错误的,根据编码不同,所需字节也不同)
字符集: 字符按编码规则,能表示出来的字符集合,就是字符集.
各个国家和地区在制定编码标准的时候,“字符的集合”和“编码”一般都是同时制定的。因此,平常我们所说的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码”的含义。
| 系统内码 | 说明 | 系统 |
阶段一 | ASCII | 计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。 | 英文 DOS |
阶段二 | ANSI编码 (本地化) | 为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。 不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 | 中文 DOS,中文 Windows 95/98,日文 Windows 95/98 |
阶段三 | UNICODE (国际化) | 为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 | Windows NT/2000/XP,Linux,Java |
然后再用表格来区分下字符,字节的概念:
| 概念描述 | 举例 |
字符 | 人们使用的记号,抽象意义上的一个符号。 | '1', '中', 'a', '$', '¥', …… |
字节 | 计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。 | 0x01, 0x45, 0xFA, …… |
ANSI 字符串 | 在内存中,如果“字符”是以 ANSI 编码形式存在的,一个字符可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI 字符串或者多字节字符串。 | "中文123" (占7字节) |
UNICODE 字符串 | 在内存中,如果“字符”是以在 UNICODE 中的序号存在的,那么我们称这种字符串为UNICODE 字符串或者宽字节字符串。 | L"中文123" (占10字节) |
由于不同 ANSI 编码所规定的标准是不相同的,因此,对于一个给定的多字节字符串,我们必须知道它采用的是哪一种编码规则,才能够知道它包含了哪些“字符”。而对于 UNICODE 字符串来说,不管在什么环境下,它所代表的“字符”内容总是不变的。
2.java中的转码方式
在 C++ 和 Java 中,用来代表“字符”和“字节”的数据类型,以及进行编码的方法:
类型或操作 | C++ | Java |
字符 | wchar_t | char |
字节 | char | byte |
ANSI 字符串 | char[] | byte[] |
UNICODE 字符串 | wchar_t[] | String |
字节串→字符串 | mbstowcs(), MultiByteToWideChar() | string = new String(bytes, "encoding") |
字符串→字节串 | wcstombs(), WideCharToMultiByte() | bytes = string.getBytes("encoding") |
以上需要注意几点:
1)Java 中的 char 代表一个“UNICODE 字符(宽字节字符)”,而 C++ 中的 char 代表一个字节。
2)MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函数。
参考文章:
http://www.regexlab.com/zh/encoding.htm
http://blog.csdn.net/ygj281583295/article/details/4035386