详细内容来自:
Unicode(UTF-8, UTF-16)令人混淆的概念
Java 语言中一个字符占几个字节?(知乎)
unicode和UTF
1.unicode:统一的字符编号,仅仅提供字符与编号间的映射。由于历史遗留及口语化原因,说起unicode,也常指UTF-16。
2.UTF:unicode transformation format ,即unicode具体的实现方式。
(1)UTF-16:
旧标准中:这个“16”意思为固定使用16位(即2字节)储存一个字符。0-127就是ASCII那些,128-65536就是扩充的那些字符,很容易理解。
新标准中:使用16位/32位来储存一个字符,不再是定长的16位。这里要注意,意思是在UTF-16编码下,可能解析一个字符时读取2个字节来解析,但下一个字符读取4个字节来解析。新标准中,UTF-16也变成不定长的编码了。
(2)UTF-8:这个“8”意思为8位为一块(说了等于没说系列)。
这个“8”很容易误导人。实际上它是不定长编码,使用8位/16位/24位/32位来储存一个字符。
(3)UTF-32:固定使用32位储存一个字符,是定长编码。
3.c++中字符char的问题:
(1)char c='中';
将发生截断,c中并不是储存着这个'中'
。
首先编译器将检测你的系统默认编码(如GBK),把这个'中'
转换为一个int的值(int占4字节,足够表示了),然后把这个int强制转换为char,赋值给c,发生截断。这里可见,c++不能使用一个char来储存一个中文字符。
(2)char arr[3]="中"
正确。
编译器处理时,将使用两个字节( char[0]和char[1] )来储存'中'
(对应的int的低16位),同时为char[2]赋值'\0'
。即此时必须借助char数组
4.java中char的问题:
(1)java中字符占2字节,与c++的不同
(2)java内部编码采用UTF-16。但是新标准中UTF-16是不定长编码,一个字符可能为2/4字节,所以实际上java中char依然有这个问题。如果某个字符需要4字节,那么将发生截断,低2字节将被赋值到char中。实际上4字节的那些字符,很难打出来的,一般能输入进去的话都没问题。
(3)String类由char[]当储存结构,但是屏蔽了UTF-16不定长造成的差异。也就是说如果一个字符串由两个4字节的字符组成,那么String.length依然为2,且此时打印String依然能正确输出。详细看一开始就贴出来的链接。
(4)内部编码和外部编码:
内码是程序内部使用的字符编码,特别是某种语言实现其char或String类型在内存里用的内部编码;
外码是程序与外部交互时外部使用的字符编码。“外部”相对“内部”而言;不是char或String在内存里用的内部编码的地方都可以认为是“外部”。
详细看一开始就贴出来的链接。
5.编码
unicode编码表中的第20013号字符为'中'
,其中
(1)UTF-16BE(BE意思为大端):
很简单,直接把十进制的20013用16位二进制表示即可:
01001110 00101101
(2)UTF-8:
建议自行去了解UTF-8的规则。这里显然需要三个字节的格式1110xxxx 10xxxxxx 10xxxxxx
,把对应的二进制填入即可:
11100100 10111000 10101101
(3)你值得拥有的查看unicode编码的网站:Unicode®字符百科
url编码
问题:http://localhost?a=1&b=2
,url中的查询参数是什么?
很明显是a=1
和b=2
。但为什么不理解为a= "1&b=2"
这个字符串呢?
这问题出在&
这个字符,跟我们字符串的反斜杠\
差不多道理,&
是一个特殊意义的符号。后端将把这个字符当作分割用的标记(=
、?
和其他符号基本同理)。
也就是如果我们需要传送a= "1&b=2"
时,应该写成http://localhost?a=1%26b%3D2
。其中%26就表示&
,%3D就表示=
,更多转义可以查看url编码规则。
1.urlencoded:
url编码是基于unicode/GBK等编码的一种编码方式,以解决上面提到的和其他(中文传输)问题。
一个最简单的例子,如前面例子字符串"中"
的UTF-8编码为E4 B8 AD
,那么urlencoded后,就是字符串%E4%B8%AD
。如果是基于UTF-16BE,那么urlencoded后就是字符串%4E%2D
。
显然,对不同编码的字符(如中文),urlencoded出来的结果可能有所不同。而对于&=?这些特殊符号,编码规则是一定的
2.application/x-www-form-urlencoded
是http头content-type的可选值之一,意味着当前请求参数/实体内容进行过urlencoded。此外application/x-www-form-urlencoded; charset=UTF-8
表明这个urlencoded是基于UTF-8编码的,避免解码时出错。
3.post方式时
(1)application/x-www-form-urlencoded; charset=UTF-8
描述如上,请了解浏览器表单默认自动编码提交和自己手动提交的区别,避免进行两次urlencoded或没有urlencoded
(2)application/json; charset=UTF-8
没有进行url编码。因为此时后端不需要&
符号来做分隔符,直接传json字符串就是
(3)multipart/form-data
没有进行url编码。因为此时后端不需要&
符号来做分隔符,而是使用一种特殊分隔符,详细右转百度
网友评论