通过javascript进行UTF-8编码的实现方法

javascript的字符集:

javascript程序是使用Unicode字符集编写的。Unicode是ASCII和Latin-1的超集,并支持地球上几乎所有的语言。ECMAScript3要求JavaScript必须支持Unicode2.1及后续版本,ECMAScript5则要求支持Unicode3及后续版本。所以,我们编写出来的

javascript程序,都是使用Unicode编码的。

UTF-8

UTF-8(UTF8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码。

它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或发送文字的应用中,优先采用的编码。

目前大部分的网站,都是使用的UTF-8编码。

将javascript生成的Unicode编码字符串转为UTF-8编码的字符串

如标题所说的应用场景十分常见,例如发送一段二进制到服务器时,服务器规定该二进制内容的编码必须为UTF-8。这种情况下,我们必须就要通过程序将javascript的Unicode字符串转为UTF-8编码的字符串。

转换方法

转换之前我们必须了解Unicode的编码结构是固定的。

不信可以试一试 String 的 charCodeAt 这个方法,看看返回的 charCode 占几个字节。

•英文占1个字符,汉字占2个字符

然而,UTF-8的编码结构长度是根据某单个字符的大小来决定长度有多少。

下面为单个字符的大小占用几个字节。单个unicode字符编码之后的最大长度为6个字节。

•1个字节:Unicode码为0 - 127
•2个字节:Unicode码为128 - 2047
•3个字节:Unicode码为2048 - 0xFFFF
•4个字节:Unicode码为65536 - 0x1FFFFF
•5个字节:Unicode码为0x200000 - 0x3FFFFFF
•6个字节:Unicode码为0x4000000 - 0x7FFFFFFF

具体请看图片:

因为英文和英文字符的Unicode码为0 - 127,所以英文在Unicode和UTF-8中的长度和字节都是一致的,只占用1个字节。这也就是为什么UTF8是Unicode的超集!

现在我们再来讨论汉字,因为汉字的unicode码区间为0x2e80 - 0x9fff, 所以汉字在UTF8中的长度最长为3个字节。

那么汉字是如何从Unicode的2个字节转换为UTF8的三个字节的哪?

假设我需要把汉字"中"转为UTF-8的编码

1、获取汉字Unicode值大小

var str = '中';
var charCode = str.charCodeAt(0);
console.log(charCode); // => 20013

2、根据大小判断UTF8的长度

由上一步我们得到汉字"中"的charCode为20013.然后我们发现20013位于2048 - 0xFFFF这个区间里,所以汉字"中"应该在UTF8中占3个字节。

3、补码

既然知道汉字"中"需要占3个字节,那么这3个字节如何得到哪?

这就需要设计到补码,具体补码逻辑如下:

好吧,我知道这个图你们也看不明白,还是我来讲吧!

具体的补位码如下,"x"表示空位,用来补位的。

•0xxxxxxx
•110xxxxx 10xxxxxx
•1110xxxx 10xxxxxx 10xxxxxx
•11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
•111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
•1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

warning:有没有发现?补位码第一个字节前面有几个1就表示整个UTF-8编码占多少个字节!UTF-8解码为Unicode就是利用的这个特点哦~

我们先举个简单的例子。把英文字母"A"转为UTF8编码。

1、“A”的charCode为65
2、65位于0-127的区间,所以“A”占一个字节
3、UTF8中一个字节的补位为0xxxxxxx,x表示的是空位,是用来补位的。
4、将65转为二进制得到1000001
5、将1000001按照从前到后的顺序,依次补到1xxxxxxx的空位中,得到01000001
6、将11000001转为字符串,得到"A"
7、最终,"A"为UTF8编码之后“A”

通过这个小例子,我们是否再次验证了UTF-8是Unicode的超集!

好了,我们现在再回到汉字"中"上,之前我们已经得到了"中"的charCode为20013,二进制为01001110 00101101。具体如下:

var code = 20013;
code.toString(2);
// => 100111000101101 等同于 01001110 00101101

然后,我们按照上面“A”补位的方法,来给"中"补位。
将01001110 00101101按照从前到后的顺序依此补位到1110xxxx 10xxxxxx 10xxxxxx上.得到11100100 10111000 10101101.

4、得到UTF8编码的内容

通过上面的步骤,我们得到了"中"的三个UTF8字节,11100100 10111000 10101101。

我们将每个字节转为16进制,得到0xE4 0xB8 0xAD;
那么这个0xE4 0xB8 0xAD就是我们最终得到的UTF8编码了。

我们使用nodejs的buffer来验证一下是否正确。

var buffer = new Buffer('中');
console.log(buffer.length); // => 3
console.log(buffer); // => <Buffer e4 b8 ad>
// 最终得到三个字节 0xe4 0xb8 0xad

因为16进制是不分大小写的,所以是不是跟我们算出来0xE4 0xB8 0xAD一模一样。

将上面的编码逻辑写到一个函数中。

// 将字符串格式化为UTF8编码的字节
var writeUTF = function (str, isGetBytes) {
   var back = [];
   var byteSize = 0;
   for (var i = 0; i < str.length; i++) {
     var code = str.charCodeAt(i);
     if (0x00 <= code && code <= 0x7f) {
        byteSize += 1;
        back.push(code);
     } else if (0x80 <= code && code <= 0x7ff) {
        byteSize += 2;
        back.push((192 | (31 & (code >> 6))));
        back.push((128 | (63 & code)))
     } else if ((0x800 <= code && code <= 0xd7ff)
         || (0xe000 <= code && code <= 0xffff)) {
        byteSize += 3;
        back.push((224 | (15 & (code >> 12))));
        back.push((128 | (63 & (code >> 6))));
        back.push((128 | (63 & code)))
     }
    }
    for (i = 0; i < back.length; i++) {
      back[i] &= 0xff;
    }
    if (isGetBytes) {
      return back
    }
    if (byteSize <= 0xff) {
      return [0, byteSize].concat(back);
    } else {
      return [byteSize >> 8, byteSize & 0xff].concat(back);
    }
}

writeUTF('中'); // => [0, 3, 228, 184, 173]
// 前两位表示后面utf8字节的长度。因为长度为3,所以前两个字节为`0,3`
// 内容为`228, 184, 173`转成16进制就是`0xE4 0xB8 0xAD`
// 读取UTF8编码的字节,并专为Unicode的字符串
var readUTF = function (arr) {
  if (typeof arr === 'string') {
    return arr;
  }
  var UTF = '', _arr = this.init(arr);
  for (var i = 0; i < _arr.length; i++) {
    var one = _arr[i].toString(2),
        v = one.match(/^1+?(?=0)/);
    if (v && one.length == 8) {
      var bytesLength = v[0].length;
      var store = _arr[i].toString(2).slice(7 - bytesLength);
      for (var st = 1; st < bytesLength; st++) {
        store += _arr[st + i].toString(2).slice(2)
      }
      UTF += String.fromCharCode(parseInt(store, 2));
      i += bytesLength - 1
    } else {
      UTF += String.fromCharCode(_arr[i])
    }
  }
  return UTF
}

readUTF([0, 3, 228, 184, 173]); => '中'

另外一种将中文解析得到UTF8字节码的方法

另外一种比较简单的将中文转为UTF8字节码的方法比较简单,浏览器也提供了一个方法,而且这个方法大家都一直在用,是什么哪?就是encodeURI。当然,encodeURIComponent也是可以的。

没错,就是这个方法。那么这个方法是怎么将一个Unicode编码的中文转为UTF8的字节码嘞?

var str = '中';

var code = encodeURI(str);

console.log(code); // => %E4%B8%AD

有没有发现得到了一个转义后的字符串,而且这个字符串中的内容和我之前在上面得到的字节码是一样的~~~。

下面我们将%E4%B8%AD转为一个number数组。

var codeList = code.split('%');

codeList = codeList.map(item => parseInt(item,16));

console.log(codeList); // => [228, 184, 173]

如此简单,有木有~~~

这个简便方法的原理是什么?

这里就涉及到的URI中的querystring编码的问题了。因为按照规定,URI中的querystring必须按照UTF8的编码进行传输,而JavaScript是Unicode的,所以浏览器就给我们提供了一个方法,也就是encodeURI/encodeURIComponent方法。这个方法会讲
非英文字符(这里考虑下,为什么是非英文字符?)先转为UTF8的字节码,然后前面加个%进行拼接,所以我们将汉字"中"转义下便得到了"%E4%B8%AD".

好吧,原理就这些,没有其他的了。

不过,这种方法还有个缺点,那就是只会转义非英文字符,所以当我们需要将英文字符也格式化为UTF8编码时,这个方法是达不到我们需求的,我们还需要额外的将英文字符也给转义下。

那我想要解析回来应该怎么做哪?用decodeURI/decodeURIComponent就可以了。

var codeList = [228, 184, 173];

var code = codeList.map(item => '%'+item.toString(16)).join('');

decodeURI(code); // => 中

好了,到这里本文也就介绍完UTF8的编码了。
希望可以帮助大家了解到UTF-8编码的原理。

以上就是小编为大家带来的通过javascript进行UTF-8编码的实现方法全部内容了,希望大家多多支持我们~

(0)

相关推荐

  • JavaScript中字符串与Unicode编码互相转换的实现方法

    本文实例讲述了JavaScript中字符串与Unicode编码互相转换的实现方法.分享给大家供大家参考,具体如下: 这段代码演示了JavaScript中字符串与Unicode编码的转换: // 为了控制台的演示方便, 变量没有添加 var 定义 // 实际编程中请避免 // 字符串 str = "中文"; // 获取字符 char0 = str.charAt(0); // "中" // 数字编码值 code = str.charCodeAt(0); // 20013

  • JavaScript字符串对象fromCharCode方法入门实例(用于把Unicode值转换为字符串)

    JavaScript fromCharCode 方法 fromCharCode 方法用于把一个或多个 Unicode 值转换为(大写)字符串,并返回该字符串.其语法如下: 复制代码 代码如下: String.fromCharCode( num1, num2, ... ) 参数说明: 参数 说明 num1/num2 必需.Unicode 编码值 提示:该方法是 String 的静态方法,它的语法应该是 String.fromCharCode(),而不适用于您自己创建的 String 对象. fro

  • 将字符串转换成gb2312或者utf-8编码的参数(js版)

    在很多时候,我们直接在url中传递中文参数时,读到的中文都是乱码,那么我们应该怎么将这些参数转换呢? 下面我们来介绍一下方法 1.我们新建一个 UrlEncode.js 然后将下面的代码拷贝进去 复制代码 代码如下: //JS版的Server.UrlEncode编码函数 String.prototype.UrlEncodeGB2312 = function () { var str = this; str = str.replace(/./g, function (sHex) { window.

  • js中unicode转码方法详解

    有时候遇到unicode不得不转码,我们只好人工编码进行转码.昨天在网上看到一个unitcode转码的方法,非常好用!小编把它和大家分享一下. JavaScript脚本UniCode转码函数: <script type="text/javascript"> var GB2312UnicodeConverter = { ToUnicode: function (str) { return escape(str).toLocaleLowerCase().replace(/%u/

  • javascript实现unicode与ASCII相互转换的方法

    本文实例讲述了javascript实现unicode与ASCII相互转换的方法.分享给大家供大家参考,具体如下: <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>Unicode.ASCII相互转换</title> <script type="text/javascript"&g

  • utf-8编码引起js输出中文乱码的解决办法

    编码规则是utf-8,如网页头中的: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 那么js文件中如果有中文输出就会出现乱码,解决此个问题有两个方法: 1.在引用javascript输出的地方加上charset="gb2312" 或 charset="big5"(假设输出的是Big5繁体字). 例: <script

  • Json_encode防止汉字转义成unicode的方法

    大家都知道,json_encode通常会把json中的汉字转义成unicode,但是这并不一定是我们想要的.有时候,我们需要获得汉字形式的json字符串,比如需要获得gbk编码的json字符串(只要把汉字形式的字符串转码就可以得到了).有什么好办法么? php官方听到了这个需求,并提供了一种可靠的解决方案:JSON_UNESCAPED_UNICODE.这个参数可以保证json_encode不再将汉字转为unicode. 似乎这样就解决了?当我们高高兴兴的用这个参数的时候,发现并没有什么卵用.仔细

  • JS失效 提示HTML1114: (UNICODE 字节顺序标记)的代码页 utf-8 覆盖(META 标记)的冲突的代码页 utf-8

    经过分析发现,这个是因为页面中html与js编码不一致导致的,一般情况最好统一标准的utf8的 上网找了找,木有找到相关的解决办法,索性自己试了试. 原页面是这样写的: <html> <head> <meta http-equiv="Content-Type" content="text/html charset=UTF-8" /> <script type="text/javascript" src=&

  • JS实现unicode和UTF-8之间的互相转换互转

    有一设备,为短信网关.需将PC送过来的UTF-8转换成UNICODE才能将内容通过短信发送出去,同样,接收到的短信为unicode编码,也许转换成UTF-8才能在PC端软件显示出来.程序很简单,只是走了不少弯路: //unicode为1个接收数据,串口收到的字符编码放在该数组中 function UnicodeToUtf8(unicode) { var uchar; var utf8str = ""; var i; for(i=0; i<unicode.length;i+=2){

  • 通过javascript进行UTF-8编码的实现方法

    javascript的字符集: javascript程序是使用Unicode字符集编写的.Unicode是ASCII和Latin-1的超集,并支持地球上几乎所有的语言.ECMAScript3要求JavaScript必须支持Unicode2.1及后续版本,ECMAScript5则要求支持Unicode3及后续版本.所以,我们编写出来的 javascript程序,都是使用Unicode编码的. UTF-8 UTF-8(UTF8-bit Unicode Transformation Format)是一

  • JavaScript将字符串转换成字符编码列表的方法

    本文实例讲述了JavaScript将字符串转换成字符编码列表的方法.分享给大家供大家参考.具体如下: JavaScript将字符串转换成字符编码列表,例如foo转换成 [112,111,111] 方法 1: JavaScript 1.6 Array.map('foo', function(x) { return String.charCodeAt(x) }) // is [112,111,111] 方法2: JavaScript 1.7 [ String.charCodeAt(x) for ea

  • javascript url几种编码方式详解

    1. escape() 不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值.比如"春节"的返回结果是%u6625%u8282,escape()不对"+"编码主要用于汉子编码,现在已经不提倡使用了. 2. encodeURI()是javascript中真正用来对URL编码的函数.编码整个URL地址,但对特殊含义的符号";/?:@&=+$,#",也不进行编码.对应的解码函数是decodeURI(). 3. encodeU

  • asp(JavaScript)自动判断网页编码并转换的代码

    完整的示例代码如下: 复制代码 代码如下: <%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>JavaScript自动判断网页编码并转换</titl

  • ANSI,Unicode,BMP,UTF等编码概念实例讲解

    一.前言 其实从开始写Java代码以来,我遇到过无数次乱码与转码问题,比如从文本文件读入到String出现乱码,Servlet中获取HTTP请求参数出现乱码,JDBC查询到的数据乱码等等,这些问题很常见,遇到的时候随手搜一下都可以顺利解决,所以没有深入的去了解. 直到前两天同学与我谈起一个Java源文件的编码问题(这问题在最后一个实例分析),从这个问题入手拉扯出了一连串的问题,然后我们一边查资料一边讨论,直到深夜,终于在一篇博客中找到了关键性线索,解决了所有的疑惑,以前没有理解的语句都能解释清楚

  • Python中字符编码简介、方法及使用建议

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有英文,而单字节可以表示256个不同的字符,可以表示所有的英文字符和许多的控制符号.不过ASCII只用到了其中的一半(\x80以下),这也是MBCS得以实现的基础. 1.2. MBCS 然而计算机世界里很快就有了其他语言,单字节的ASCII已无法满足需求.后来每个语言就制定了一套自己的编码,由于单字节

  • php使用fopen创建utf8编码文件的方法

    本文实例讲述了php使用fopen创建utf8编码文件的方法.分享给大家供大家参考.具体实现方法如下: 一般来说,如果我们直接使用fopen创建会发现文件编码都不是uft-8的了,那么如果要创建uft8文件我们需要进行一些技术处理.具体步骤如下: 使用PHP创建编码格式为utf-8文件的方法: 第一步:新建一个txt文件,打开,文件->另存为xxx.php,并将编码改为UTF-8,保存. 第二部:在php文件中加入如下代码: 复制代码 代码如下: <?php $filename=rand(10

  • javascript实现全角转半角的方法

    本文实例讲述了javascript实现全角转半角的方法.分享给大家供大家参考,具体如下: function fullChar2halfChar(str) { var result = ''; for (i=0 ; i<str.length; i++) { code = str.charCodeAt(i);//获取当前字符的unicode编码 if (code >= 65281 && code <= 65373)//在这个unicode编码范围中的是所有的英文字母已经各种字

  • 超精准的javascript验证身份证号的具体实现方法

    编写程序前先来了解下身份证号的构成: 身份证号分为两种,旧的为15位,新的为18位. 身份证15位编码规则:dddddd yymmdd xx p    其中 dddddd:地区码    yymmdd: 出生年月日    xx: 顺序类编码,无法确定    p: 性别,奇数为男,偶数为女: 身份证18位编码规则:dddddd yyyymmdd xxx y    其中 dddddd:地区码    yyyymmdd: 出生年月日     xxx:顺序类编码,无法确定,奇数为男,偶数为女    y: 校

  • php头编码实例设置方法及代码

    在PHP中可以通过在PHP文件头部添加"header("Content-type: text/html; charset=utf-8");"语句来设置编码. 设置utf编码的代码如下: header("Content-type: text/html; charset=utf-8"); 注:通常情况以上代码放在php页面的首页 header() 函数向客户端发送原始的 HTTP 报头. 附: php页面为gbk编码 header("Con

随机推荐