编码解码Tips
编码与解码
- 关于编码与解码的一些基础要点
编码与解码
- 计算机中存储和传输的是二进制的序列流,最小的抽象单元是字节,即8个二进制位(1 byte = 8 bits), 转换为10进制,就是一个0~255的数字
- 计算机中所有的文件数据都可以表示为0~255数字的一个数组,即字节数组
- 人类眼睛直观观察的是字符(char),而不是字节数组(愚蠢的人类),所以需要在需要的时候进行转换,比如网页浏览
- 转换的过程就是一个翻译映射的过程,对于计算机来说,这个过程就是字节数组映射到字符的过程,这个过程,就叫做编码
- 翻译是需要一本字典的,不然如何知道新的语言(如何表示老的语言呢),所以就出现了各种编码的格式,每一种编码就是一种将字节数组转换成字符的规则函数
f(x)
编码 | 包含字符数 | 每个字符需要的字节数 | 备注 |
---|---|---|---|
ASCII | 128 | 1 | —– |
ISO-8859-1 | 256 | 1 | 扩展了ASCII, 兼容ASCII |
GB2312 | 682个符号 6763个汉字 | 2 | 中文编码字节表 |
GBK | 23940个码位 21003个汉字 | 2 | 汉字内码扩展规范,兼容了GB2312 |
UTF-16 | 23940个码位 21003个汉字 | 定长2字节 | ISO指定的统一码,Java内存使用此编码表示Char |
UTF-8 | 23940个码位 21003个汉字 | 变长1-6字节 | ISO指定的统一码,Java内存使用此编码表示Char |
Java Web中的编解码
- 发送request请求需要编码,url、表单、header等信息均需要编码传送socket
- URL的编解码
- URL中的pathinfo与参数(?后面的内容)采用的编码方式不一样,Tomcat接收到这样的请求后,需要对URL进行解码,此时需要获取字符集,配置于Tomcat的Connector配置中,若没有则使用默认字符集进行解码
- 要避免在URL中使用非ASCII码字符
- Header中的编解码
- header中的字符解码Tomcat默认使用的iso-8859-1编码方式,在添加header时需要使用URLEncoder进行编码
- 不要再header中添加使用非ASCII码字符
- Post表单请求的编解码
- 浏览器使用Content-Type中的字符集进行编码后发送请求
- 上传的文件,即multipart/form-data类型的数据,同样也是用Content-Type中的字符集进行编码,上传文件是以字节流的方式存储文件至临时目录,所以不存在编码问题,Spring MVC可以直接获取文件的流,推荐使用这种方式,省去了编解码的识别问题
- http的response Body编解码
- 服务端可以设置response.setCharacterEncoding()来设置Content-Type,浏览器将以header中的Content-Type开解码数据,
- 如果没有设置,则浏览器以HTML中的Meta信息中的字符集进行解码,否则就是使用默认的字符集进行解码
几个常见的问题
- 中文变成了看不懂的符号:使用了不一致的编解码字符集,如gbk编码->8859解码
- 汉字变成了问号:使用了不支持中文的字符集编码,如使用8859编码中文
- 一个汉字变2个问号:中文经过了多次编解码,如 gbk编码->8859解码->gbk编码->gbk解码