关于js中用base64编码处理中文的问题
2017-01-13 18:11
453 查看
之前在网上找了一个js版用base64编码在方法,发现不能处理中文,今天有幸找了一篇专门介绍js中用base64编码的文章,不仅讲解了原理,又给出了实现方法,写的比较好,收藏了。
原文地址--
Base64是最常用的编码之一,比如开发中用于传递参数、现代浏览器中的<img />标签直接通过Base64字符串来渲染图片以及用于邮件中等等。Base64编码在RFC2045中定义,它被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。
我们知道,任何数据在计算机中都是以二进制的方式存储的。一个字节为8位,一个字符在计算机中存储为一个或多个字节,比如英文字母、数字以及英文标点符号就是用一个 字节来存储的,通常称为ASCII码。而简体中文、繁体中文、日文以及韩文等都是用多字节来存储的,通常称为多字节字符。因为Base64编码是对字符串的编码表示进行处理的,不同编码的字符串的Base64的结果是不同的,所以我们需要了解基本的字符编码知识。
为了提高计算机的信息处理和交换功能,使得世界各国的文字都能在计算机中处理,从1984年起,ISO组织就开始研究制定一个全新的标准:通用多八位(即多字节)编码字符集(Universal Multiple-Octet Coded Character Set),简称UCS。标准的编号为:ISO 10646。这一标准为世界各种主要语言的字符(包括简体及繁体的中文字)及附加符号,编制统一的内码。
统一码(Unicode)是Universal Code的缩写,是由另一个叫“Unicode学术学会”(The Unicode Consortium)的机构制定的字符编码系统。Unicode与ISO 10646国际编码标准从内容上来说是同步一致的。具体可参考:Unicode 。
Unicode
Unicode编码是和字符表一一映射的。比如56DE代表汉字'回',这种映射关系是固定不变的。通俗的说Unicode编码就是字符表的坐标,通过56DE就能找到汉字'回'。Unicode编码的实现包括UTF8、UTF16、UTF32等等。
Unicode本身定义的就是每个字符的数值,是字符和自然数的映射关系,而UTF-8或者UTF-16甚至UTF-32则定义了如何在字节流中断字,是计算机领域的概念。
通过上图我们知道,UTF-8编码为变长的编码方式,占1~6个字节,可通过Unicode编码值的区间来判断,并且每个组成UTF8字符的字节都是有规律可循的。本文只讨论UTF8和UTF16这两种编码。
我们看到有4个字节,前2个字节FF FE是文件头,表示这是一个UTF16编码的文件,而DE 56则是'回'的UTF16编码的十六进制。我们经常使用的JavaScript语言,它内部就是采用UTF16编码,并且它的存储方式为大端序,来看一个例子:
很明显跟刚才Editplus显示的不一样,顺序是相反的,这是因为字节序不一样。具体可参考:UTF-16 。
知道了转换规则,就很容易实现了。
原文地址--
Base64是最常用的编码之一,比如开发中用于传递参数、现代浏览器中的<img />标签直接通过Base64字符串来渲染图片以及用于邮件中等等。Base64编码在RFC2045中定义,它被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。
我们知道,任何数据在计算机中都是以二进制的方式存储的。一个字节为8位,一个字符在计算机中存储为一个或多个字节,比如英文字母、数字以及英文标点符号就是用一个 字节来存储的,通常称为ASCII码。而简体中文、繁体中文、日文以及韩文等都是用多字节来存储的,通常称为多字节字符。因为Base64编码是对字符串的编码表示进行处理的,不同编码的字符串的Base64的结果是不同的,所以我们需要了解基本的字符编码知识。
字符编码基础
计算机最开始只支持ASCII码,一个字符用一个字节表示,只用了低7位,最高位为0,因此总共有128个ASCII码,范围为0~127。后来为了支持多种地区的语言,各大组织机构和IT厂商开始发明它们自己的编码方案,以便弥补ASCII编码的不足,如GB2312编码、GBK编码和Big5编码等。但这些编码都只是针对局部地区或少数语言文字,没有办法表达所有的语言文字。而且这些不同的编码之间并没有任何联系,它们之间的转换需要通过查表来实现。为了提高计算机的信息处理和交换功能,使得世界各国的文字都能在计算机中处理,从1984年起,ISO组织就开始研究制定一个全新的标准:通用多八位(即多字节)编码字符集(Universal Multiple-Octet Coded Character Set),简称UCS。标准的编号为:ISO 10646。这一标准为世界各种主要语言的字符(包括简体及繁体的中文字)及附加符号,编制统一的内码。
统一码(Unicode)是Universal Code的缩写,是由另一个叫“Unicode学术学会”(The Unicode Consortium)的机构制定的字符编码系统。Unicode与ISO 10646国际编码标准从内容上来说是同步一致的。具体可参考:Unicode 。
ANSI
ANSI不代表具体的编码,它是指本地编码。比如在简体版windows上它表示GB2312编码,在繁体版windows上它表示Big5编码,在日文操作系统上它表示JIS编码。所以如果您新建了个文本文件并保存为ANSI编码,那么您现在应该知道这个文件的编码为本地编码。Unicode
Unicode编码是和字符表一一映射的。比如56DE代表汉字'回',这种映射关系是固定不变的。通俗的说Unicode编码就是字符表的坐标,通过56DE就能找到汉字'回'。Unicode编码的实现包括UTF8、UTF16、UTF32等等。Unicode本身定义的就是每个字符的数值,是字符和自然数的映射关系,而UTF-8或者UTF-16甚至UTF-32则定义了如何在字节流中断字,是计算机领域的概念。
通过上图我们知道,UTF-8编码为变长的编码方式,占1~6个字节,可通过Unicode编码值的区间来判断,并且每个组成UTF8字符的字节都是有规律可循的。本文只讨论UTF8和UTF16这两种编码。
UTF16
UTF16编码使用固定的2个字节来存储。因为是多字节存储,所以它的存储方式分为2种:大端序和小端序。UTF16编码是Unicode最直接的实现方式,通常我们在windows上新建文本文件后保存为Unicode编码,其实就是保存为UTF16编码。UTF16编码在windows上采用小端序的方式存储,以下我新建了个文本文件并保存为Unicode编码来测试,文件中只输入了一个汉字'回',之后我用Editplus打开它,切换到十六进制方式查看,如图所示:我们看到有4个字节,前2个字节FF FE是文件头,表示这是一个UTF16编码的文件,而DE 56则是'回'的UTF16编码的十六进制。我们经常使用的JavaScript语言,它内部就是采用UTF16编码,并且它的存储方式为大端序,来看一个例子:
<script type="text/javascript"> console.group('Test Unicode: '); console.log(('回'.charCodeAt(0)).toString(16).toUpperCase()); </script>
很明显跟刚才Editplus显示的不一样,顺序是相反的,这是因为字节序不一样。具体可参考:UTF-16 。
<script type="text/javascript"> /** * 转换对照表 * U+00000000 – U+0000007F 0xxxxxxx * U+00000080 – U+000007FF 110xxxxx 10xxxxxx * U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx * U+00010000 – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx * U+00200000 – U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx * U+04000000 – U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ /* * '回'的Unicode编码为:0x56DE,它介于U+00000800 – U+0000FFFF之间,所以它占用三个字节。 * U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx */ var ucode = 0x56DE; // 1110xxxx var byte1 = 0xE0 | ((ucode >> 12) & 0x0F); // 10xxxxxx var byte2 = 0x80 | ((ucode >> 6) & 0x3F); // 10xxxxxx var byte3 = 0x80 | (ucode & 0x3F); var utf8 = String.fromCharCode(byte1) + String.fromCharCode(byte2) + String.fromCharCode(byte3); console.group('Test UTF16ToUTF8: '); console.log(utf8); console.groupEnd(); /** ------------------------------------------------------------------------------------*/ // 由三个字节组成,所以分别取出 var c1 = utf8.charCodeAt(0); var c2 = utf8.charCodeAt(1); var c3 = utf8.charCodeAt(2); /* * 需要通过判断特定位的方式来转换,但这里是已知是三个字节,所以忽略判断,而是直接拿到所有的x,组成16位。 * U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx */ // 丢弃第一个字节的高四位并和第二个字节的高四位组成一个字节 var b1 = (c1 << 4) | ((c2 >> 2) & 0x0F); // 同理第二个字节和第三个字节组合 var b2 = ((c2 & 0x03) << 6) | (c3 & 0x3F); // 将b1和b2组成16位 var ucode = ((b1 & 0x00FF) << 8) | b2; console.group('Test UTF8ToUTF16: '); console.log(ucode.toString(16).toUpperCase(), String.fromCharCode(ucode)); console.groupEnd(); </script>
知道了转换规则,就很容易实现了。
相关文章推荐
- 通过读写文本文件小结“关于python处理中文编码的问题”
- Base64 JAVA后台编码与JS前台解码(解决中文乱码问题)
- 通过读写文本文件小结“关于python处理中文编码的问题”
- Base64 JAVA后台编码与JS前台解码(解决中文乱码问题)
- 关于中文编码问题及Java中的处理
- 在Python中关于中文编码问题的处理建议
- 关于php与js传递cookie中文值编码问题
- 关于sharp map 的中文编码问题
- 关于中文字符UNICODE编码的三个问题(基于此可以求中文字符的笔划和首拼)
- 关于hibernate和jsp,以及中文编码问题的传统解决方法
- 用javascript实现Base64编码(解决中文问题C#里解码) 转
- ajax提交中文编码问题(同时给出几个js与php编码方式)
- MyEclipse中 js中文乱码问题 VS MyEclipse默认编码
- 利用python处理xml -- 中文编码问题
- 关于js文件中的中文问题
- 关于解决属性文件中文编码错误不能保存的问题
- 关于中国的字符集编码问题--纯粹个人的观点--中文乱码问题
- 关于js和c#的编码的问题
- 关于处理Excel表中文字不能自动换行问题
- 关于perl处理excle(中文编码字符,Spreadsheet::Read)