您好,登录后才能下订单哦!
GBK与UTF-8的区别是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
GBK与UTF-8的区别:
GBK是在国家标准GB2312基础上扩容后兼容GB2312的标准。GBK编码专门用来解决中文编码的,是双字节的。不论中英文都是双字节的。支持持简体中文。
UTF-8 编码是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。
如果是外国人访问GBK的系统,需要下载中文语言包支持。
GBK包含全部中文字符(含生僻字);UTF-8则包含全世界所有国家需要用到的字符。
如果主要做中文程序的开发,客户也主要是中国用户的话就用GBK,因为UTF-8编码的中文使用了三个字节,用GBK节省了空间(两字节)。
GBK改造成UTF-8的风险:
最早使用GB2312,历史上遇到过中文生僻字乱码的问题(主要是客户姓名,起名字时为了一些好彩头会选一些生僻汉字),后改为GBK才完整兼容。
如果改造成UTF-8,各业务环节都要做中文及生僻字的回归测试,测试成本较高。
我们还是推荐客户安装中文语言包的支持,目前外资客户,都选择安装了中文语言包。
GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:
用UTF-8表示英文字符用1个字节,表示 中文用3个字节。GBK是中国造的字符编码标准,长度为2个字节。因此,这两个字符集进行转换,需要中间通过Unicode编码进行过渡。
GBK、GB2312 ----》Unicode ----》UTF8
UTF8 ----》 Unicode ----》GBK、GB2312
人们为世界所有字符都编了码,叫做 Unicode(统一字符码)。在被编了码的字符中,很多字符是不经常使用的,用太长的字节表示不但浪费内存,而且大大降低读写数据库的速度(所以高性能的数据库都以ASCII为基础,比如Oracle数据库),所以提出了UTF-8(Unicode格式转换器)。
UTF-8很灵活,长度为1到6个字节,UTF-8中的8表示1个字符的长度至少是8个比特。
UTF-16比较灵活,长度为2到4个字节,UTF-16中的16表示1个字符的长度至少是16个比特。
UTF-32不灵活,长度固定4个字节,UTF-32中的32表示1个字符的长度至少是32个比特。
字符集错误转换导致的问题:
UTF8字符串-->转字节流-->按GBK转字符串(乱码)-->再转回字节流-->按UTF8转字符串(仍然乱码了)
UTF-8格式编码的字节流,按GBK字符集转换为字符串,会出现乱码,这很正常。但将其重新转为字节流,再用UTF-8字符集转为字符串,还是乱码。这就让我产生了疑惑,虽然使用错误的字符集必然导致乱码,但字节的信息并没有改变,因此再转为字节流,用正确的字符集解码,应该得到正常的字符串。但事实是,被错误字符集转换过的字符串,无法恢复到原来的字符集。
问题的根本原因
造成该问题的根源是字节长度发生了变化。
因为UTF-8编码的英文使用一个字节,中文使用三个字节,而GBK中英文都是两字节。
GBK或UTF-8遇到无法解析的字符时,会使用特殊的字符代替,因此造成原有字节信息的丢失,无法恢复。
错误转换的分析
UTF-8(三字节) → GBK(两字节)
对于一串UTF-8编码的字节流,使用GBK进行解码。连续两个大于127的字节被认为是一个GBK编码的字符;若只读到一个大于127的字节,便发生错误,无法解析。此时, 用字符 ' � ' 代替错误字节,ASCII码是63。
以 “樊”字为例,UTF-8编码使用三个字节表示该字符,字节码为[11100110, 10101000, 10001010]([e6, a8, 8a])。使用GBK解码时,读到第一个字节大于127,则取两个字节解析为一个GBK字符。前两个字节e6 8a被解析为GBK字符——妯。 第三个字节无法解析,所以赋值为�,最后的结果是 妯�。
可以看出,最后一个字节的信息丢失了,由 8a变成 3F,即使把结果再转换为字节流,也无法用utf-8字符集正确解析了。
GBK(两字节) → UTF-8(三字节)
对于一串GBK编码的字节流,使用UTF-8解码。UTF-8对于字节的格式有严格要求,当解析某个字符失败时,使用 '�'(UTF-8编码为EF BF BD)代替。
继续以 “樊”字为例,其GBK字节码为[10110111, 10101110]([B7, AE])。使用UTF-8解码时,根据规则,要求10开头的字节之前,必须有字节标识一个字符的长度,所以两个字节都无法解析。最后的字符串是��。可以看出,所有的字节信息都丢失了,因此无法再使用GBK解析该字符串。
注意,UTF-8用�替换,是以字符为单位的。例如[11100110, 10101000, 01000001]使用UTF-8解码,得到的结果是�A,而不是��A。根据第一个字节的格式,UTF-8期望将三个字节转换为一个字符。但最后一个字节不符合要求,所以前两个字节被一个�代替。而不是每个字节都被�代替。
str='学' print(str) print(len(str)) print(str.encode()) print(str.encode('GBK')) print(str.encode('UTF-8')) print(len(str.encode('GBK'))) print(len(str.encode('UTF-8'))) ----- 学 1 b'\xe5\xad\xa6' b'\xd1\xa7' b'\xe5\xad\xa6' 2 3
关于GBK与UTF-8的区别是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。