字符集编码问题
下面这三段代码在效果上有什么区别?
使用2次utf-8
// decode with base64 to get bytes
byte[] dec = BASE64DecoderStream.decode(str.getBytes("UTF-8")); 使用1次utf-8
byte[] utf8 = dcipher.doFinal(dec);
// create new string based on the specified charset
return new String(utf8, "UTF8"); 使用1次utf-8
// decode with base64 to get bytes
byte[] dec = BASE64DecoderStream.decode(str.getBytes());
byte[] utf8 = dcipher.doFinal(dec);
// create new string based on the specified charset
return new String(utf8, "UTF8");使用1次utf-8
使用1次utf-8
// decode with base64 to get bytes
byte[] dec = BASE64DecoderStream.decode(str.getBytes("UTF-8")); 使用1次utf-8
byte[] utf8 = dcipher.doFinal(dec);
// create new string based on the specified charset
return new String(utf8);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
南渊2022-09-08 18:34:21
使用1次
和使用2次
这个提法没到点上,这里次数根本不是关键。
牵扯到编码的问题,首先要认识到Java的String是无关编码的,它存储的是字符数据,而不是字节数据(尽管底层使用Unicode进行存储)
但是我们在处理各种数据的事后,总是会接触各种各样的文字的编码,比如保存进入文件时,或者进行网络传输时,这时候我们关心的是字节数据,而不是字符。
String对象的getBytes方法就是提供了编码转换成字节数据的方式,对于字节数据到低怎么编码这时候就开始需要关心了。它有多个重载,拿LZ关心的这两个来说就是
public byte[] getBytes();
public byte[] getBytes(String charsetName)
throws UnsupportedEncodingException;
这两个方法的区别其实去翻翻Java API手册就知道,前者是获取了系统当前默认编码进行编码,后者则是通过charsetName参数指定编码
同理来看String的构造方法
public String(byte[] bytes);
public String(byte[] bytes, String charsetName);
前者使用系统当前默认编码来把byte数组里面的数据解码为字符,后者通过charsetName参数指定编码
PS: 如果还是不能理解字节和字符,那么请这样考虑:一个汉字作为字符来说,是一个不可分割的个体,但是它如果用GB18030(GBK/GB2312)编码进行标示,则是2个字节长度的byte[],如果用UTF8,则是3个字节长度的byte[]
~没有更多了~
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
关于字符编码,可以参考阮大神的 字符编码笔记:ASCII,Unicode和UTF-8,尤其是里面 UTF8 的部分。这里需要用到的一个关键信息是:对于 ASCII 码为 0-127的字符,UTF8编码和ASCII编码是相同的(原文说的是对于英语字母,但其实英文字母只是其中一部分)。
现在来说你的代码
先说
String.getBytes()
,这个方法没有指定编码,会使用系统默认的编码,对于中文 Windows 系统来说,就是 GBK 编码。从
BASE64DecoderStream.decode(str.getBytes("UTF-8"))
这调用判断,str 里保存的是 Base64 编码,由 [a-zA-Z0-9+/] 这 64 个字符组成,ASCII 范围都在 0-127 之间,所以getBytes()
和getBytes("utf-8")
的区别就在于 GBK 和 UTF8 —— 而在刚才说的字符范围内,这两个编码其实没有区别,也就是说,这里你使用不使用 UTF8,结果是一样的。然后你的代码,将 base64 解码的结果进行了解密(加密解密都有可能,从逻辑上来判断,更像是解密)。至于解决的结果,是 byte[]。
OK,到这一步,你得到了 byte[] 的
utf8
,这里 utf8 只是一个变量,通常会提醒读者其保存的数据是 UTF8 编码的。顺便提一下,计算机世界,所有东西都是二进制保存,而保存的基本单位是字节,所以utf8
中保存的是啥,从目前这点程序来看,根本看不出来,只有写程序的人知道。所以,不管变量名是否 UTF8,你得知道
utf8
中的数据实际什么,只在这个数据的确是一段文本,而且使的编码明确的情况下,按这个编码生成字符串才能得到正确的结果。