当前位置: 首页 > 科技观察

什么是“昆进副本”?我答不上来,,

时间:2023-03-15 20:59:18 科技观察

周末女朋友逛街,我一个人在家看综艺。突然,我女朋友打电话给我。图片来自Pexels过了一会儿,我女朋友回来了。她拿出手机,给我看了她在超市拍的照片:想知道什么是乱码,得从电脑编码说起。字符编码和ASCII我们经常看一些谍战剧。在谍战剧中,敌特、地下党员、八路军各部门传递情报时,一般都是电报。在电报传输过程中,发件人需要用电子钥匙发出不同长度的代码,收件人会听到电报机滴答滴答的声音。其实,电报发出的声音都是“嘀”和“答”的组合,而“答”的音长是“嘀”的三倍。发送者首先要用一种方法将他要发送的信息转换成电报的滴答声,接收者在听到滴答声后将它们翻译成正常的文本。这个过程就是字符编码和字符解码。在谍战剧中,将情报转化为电报的“嘀”、“答”音主要是通过摩尔斯电码,这是一种字符编码方式,通过不同的排列顺序来表达不同的英文字母、数字和标点符号。摩尔斯电码由称为点和破折号的短电脉冲和长电脉冲组成。规定了点和破折号的持续时间。以一点为基本单位,一笔等于三个点的长度。正好对应电报的“嘀”、“答”。就像电报只能发出“嘀”和“答”的声音一样,计算机只能识别0和1这两个字符。然而,人类的字符是多种多样的。如何将人字转换成计算机可识别的01字符?,这个过程还需要字符编码。字符编码是一组规则,可用于将一组自然语言字符(例如字母表或音节)与一组其他事物(例如数字或电脉冲)配对。与摩尔斯电码的功能类似,在1960年代,美国制定了一套字符编码,对英文字符与二进制数字的关系做了统一规定。这称为ASCII码,一直沿用至今。ASCII(美国信息交换标准代码)是一种基于拉丁字母表的计算机编码系统。主要用于显示现代英语,共有128个字符,包括所有大小写字母、数字0到9、标点符号和美式英语中使用的特殊控制字符。由于ASCII只有128个字符,虽然可以表示英文字符,但是世界上还有很多其他字符他无法表示,所以需要更全面的字符编码。在介绍其他字符编码之前,先说说计算机领域常用的一个字符集。UnicodeUnicode(中文:万能码、国际码、Unicode、单一码)是计算机科学领域的一个行业标准。它组织和编码了世界上大部分的书写系统,使计算机能够以更简单的方式呈现和处理文本。Unicode仍在更新中,每个新版本都会添加更多新字符。最新版本是2019年5月发布的12.1,这个版本只增加了1个字符,就是日本新年令的连字。Unicode在计算机软件的国际化和本地化中得到广泛认可和广泛使用。许多新技术,如可扩展标记语言(ExtensibleMarkupLanguage,简称:XML)、Java编程语言、现代操作系统等,都采用了Unicode编码。Unicode是一个包含了世界上大部分文字的通用字符集,也就是说,Unicode可以表示中文。UTF-8、UTF-16、UTF-32Unicode虽然统一了全世界字符的编码,但并没有规定如何存储。这样做是有考虑的:如果Unicode统一规定,每个符号必须用3或4个字节来表示,因为字符太多,只能用这么多字节来完整表示。一旦指定,每个英文字母前必须有2到3个字节的0,因为所有英文字母在ASCII中都有,可以用1个字节表示,其余字节位置必须补0。如果这样,文本文件的大小将大两到三倍,这是一种很大的存储浪费。为了解决这个问题,出现了一些中间格式字符集,称为通用转换格式,即UTF(UnicodeTransformationFormat)。常见的UTF格式有:UTF-7UTF-7.5UTF-8UTF-16UTF-32UTF-8:每个字符编码使用1到4个字节,UTF-16:每个字符编码使用2或4个字节,UTF-32:使用4个字节对每个字符进行编码。所以我们可以说UTF-8、UTF-16等都是Unicode的实现。例如,Unicode规定一个汉字“我”对应的Unicode是“\u6211”。但是在UTF-8、UTF-16等不同的实现方式下,这个二进制码的存储方式是不一样的。.UTF-8使用变长字节来存储Unicode字符。例如ASCII字母继续使用1个字节来存储,重音文字、希腊字母或西里尔字母等使用2个字节来存储,而常用的汉字则需要使用3个字节。次平面字符使用4个字节。GBK、GB2312、GB18030因为UTF-8是Unicode的一种实现,它包含了世界上所有字符的编码,它使用1-4个字节进行编码。对于先包含的文本,可以先使用1字节或2字节存储,对于后面包含的文本,应该使用3字节或4字节存储。正是因为太全面了,所以后面收录的那些字符在UTF-8存储中可能会占用更多的字节,它的存储空间需求会很大。对于常用的汉字,在UTF-8中用3个字节编码,但如果有只包含中文和ASCII的编码,就没必要用3个字节了,也许2个字节就够了。对于大多数网站来说,它们基本上只服务于一个国家或地区。例如中文网站一般有简繁体中文和一些英文字符,很少有日文或韩文。也是出于这样的考虑,国家标准总局于1981年制定并实施了GB2312-80编码,即中华人民共和国国家标准的简体中文字符集。后来厂商微软利用GB2312-80未使用的编码空间,将GB13000.1-93的所有字符都收录进来,制定了GBK编码。有了标准的中文字符集,如果是纯中文网站,可以使用这种编码方式,可以大大节省一些存储空间。常用的中文编码有GBK、GB2312、GB18030等,最常用的是GBK。GB2312(1980),16位字符集,包含6763个简体字,682个符号,共7445个字符:优点:适合简体中文环境,属于中国国家标准,流行于中国大陆,新加坡和其他地方。缺点:不兼容繁体中文,汉字集太少。GBK(1995),16位字符集,收汉字21003个,符号883个,共21886个字符:优点:适合简繁体并存,简体Windows使用,完全兼容GB2312向下、向上支持ISO-10646国际标准;所有字符都可以一对一映射到Unicode2.0。缺点:不属于官方标准,需要在big5之间进行转换;许多搜索引擎不能很好地支持GBK汉字。GB18030(2000),32位字符集;收录了27484个汉字,还收录了藏文、蒙文、维吾尔文等主要少数民族文字:优点:可以收录你能想到的所有文字和符号,属于中国最新的国家标准。缺点:目前支持的软件较少。乱码我们以前面介绍的电报为例,假设有以下场景:发送方使用“美国摩尔斯电码”将信息转换成电报,接收方收到电报后,通过“现代国际摩尔斯电码””来解密。那么得到的信息内容可能是完全看不懂的,就是乱码。就像在计算机领域,我们把一串汉字通过UTF-8编码传输给别人,别人得到这串汉字后字符,他们通过GBK解码,得到的内容是“通勤倬应叮雮坤昆进抄直昆进抄昆”,这就是乱码。比如下面的代码:publicstaticvoidmain(String[]args)throwsUnsupportedEncodingException{Strings="Manhuaprogramming!";byte[]bytes=s.getBytes(Charset.forName("GBK"));System.out.println("GBK编码,GBK解码:"+newString(bytes,"GBK"));System.out.println("GBK编码,GB18030解码:"+newString(bytes,"GB18030"));System.out.println("GBK编码,UTF-8解码:"+newString(bytes,"UTF-8"));}输出结果:GBK编码,GBK解码:谈编程!GBK编码,GB18030解码:谈编程!GBK编码,UTF-8解码:????????可以看到汉字是GBK编码,然后UTF-8解码的。得到的字符是一串问号,是乱码。昆锦草的前世今生,是因为Unicode在不断更新。在这个过程中,肯定有一些比较新的特点,他无法表达。或者即使发布了新版本的Unicode来包含某个文本,很多软件系统没有升级也会出现这样的问题。就像生活中一些手机厂商新发布的emoji表情,在自己的手机上可以正常显示,但在其他品牌的手机上不一定能显示。这其实是字符集不支持造成的。当出现上述情况时,无法显示时,需要有一个字符来表示。在Unicode中,这个字符是?,也是Unicode中定义的一个特殊字符。即“0xFFFDREPLACEMENTCHARACTER”,所有不能表示的字符都会用这个字符表示。Unicode官方对此符号有介绍。从上表可以看出,它的十进制表示是65533,在UTF-8下,它的十六进制形式是'0xEF0xBF0xBD'(三个字节)。如果有两个连续的字符不能显示,比如“??”,那么在UTF-8编码下,十六进制表示为:0xEF0xBF0xBD0xEF0xBF0xBD上面的编码,如果用GBK解码,因为其中一个GBK汉字是两个字节,则结果为:0xEF0xBF,0xBD0xEF,0xBF0xBD,即:0xEFBF0xBDEF0xBFBD那么,如果显示,则为:坤(0xEFBF),进(0xBDEF),复制(0xBFBD)。所以,以后大家看到昆桥,第一时间肯定会想到UTF-8和GBK之间的转换问题。除了昆金文案,还有两个比较经典的乱码,分别是“唐唐唐”和“吞吞吞”。这两个乱码是VC生成的,是VC在Debug模式下对内存的初始化操作。VC会将栈中新分配的内存初始化为0xcc,将堆中新分配的内存初始化为0xcd。根据字符打印出0xcc和0xcd,暖暖的。