最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過javascript進(jìn)行UTF-8編碼的實現(xiàn)方法

 更新時間:2016年06月27日 10:21:22   投稿:jingxian  
下面小編就為大家?guī)硪黄ㄟ^javascript進(jìn)行UTF-8編碼的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

javascript的字符集:

javascript程序是使用Unicode字符集編寫的。Unicode是ASCII和Latin-1的超集,并支持地球上幾乎所有的語言。ECMAScript3要求JavaScript必須支持Unicode2.1及后續(xù)版本,ECMAScript5則要求支持Unicode3及后續(xù)版本。所以,我們編寫出來的

javascript程序,都是使用Unicode編碼的。

UTF-8

UTF-8(UTF8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字符編碼,也是一種前綴碼。

它可以用來表示Unicode標(biāo)準(zhǔn)中的任何字符,且其編碼中的第一個字節(jié)仍與ASCII兼容,這使得原來處理ASCII字符的軟件無須或只須做少部分修改,即可繼續(xù)使用。因此,它逐漸成為電子郵件、網(wǎng)頁及其他存儲或發(fā)送文字的應(yīng)用中,優(yōu)先采用的編碼。

目前大部分的網(wǎng)站,都是使用的UTF-8編碼。

將javascript生成的Unicode編碼字符串轉(zhuǎn)為UTF-8編碼的字符串

如標(biāo)題所說的應(yīng)用場景十分常見,例如發(fā)送一段二進(jìn)制到服務(wù)器時,服務(wù)器規(guī)定該二進(jìn)制內(nèi)容的編碼必須為UTF-8。這種情況下,我們必須就要通過程序?qū)avascript的Unicode字符串轉(zhuǎn)為UTF-8編碼的字符串。

轉(zhuǎn)換方法

轉(zhuǎn)換之前我們必須了解Unicode的編碼結(jié)構(gòu)是固定的。

不信可以試一試 String 的 charCodeAt 這個方法,看看返回的 charCode 占幾個字節(jié)。

•英文占1個字符,漢字占2個字符

然而,UTF-8的編碼結(jié)構(gòu)長度是根據(jù)某單個字符的大小來決定長度有多少。

下面為單個字符的大小占用幾個字節(jié)。單個unicode字符編碼之后的最大長度為6個字節(jié)。

•1個字節(jié):Unicode碼為0 - 127
•2個字節(jié):Unicode碼為128 - 2047
•3個字節(jié):Unicode碼為2048 - 0xFFFF
•4個字節(jié):Unicode碼為65536 - 0x1FFFFF
•5個字節(jié):Unicode碼為0x200000 - 0x3FFFFFF
•6個字節(jié):Unicode碼為0x4000000 - 0x7FFFFFFF

具體請看圖片:

因為英文和英文字符的Unicode碼為0 - 127,所以英文在Unicode和UTF-8中的長度和字節(jié)都是一致的,只占用1個字節(jié)。這也就是為什么UTF8是Unicode的超集!

現(xiàn)在我們再來討論漢字,因為漢字的unicode碼區(qū)間為0x2e80 - 0x9fff, 所以漢字在UTF8中的長度最長為3個字節(jié)。

那么漢字是如何從Unicode的2個字節(jié)轉(zhuǎn)換為UTF8的三個字節(jié)的哪?

假設(shè)我需要把漢字"中"轉(zhuǎn)為UTF-8的編碼

1、獲取漢字Unicode值大小

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

2、根據(jù)大小判斷UTF8的長度

由上一步我們得到漢字"中"的charCode為20013.然后我們發(fā)現(xiàn)20013位于2048 - 0xFFFF這個區(qū)間里,所以漢字"中"應(yīng)該在UTF8中占3個字節(jié)。

3、補碼

既然知道漢字"中"需要占3個字節(jié),那么這3個字節(jié)如何得到哪?

這就需要設(shè)計到補碼,具體補碼邏輯如下:

好吧,我知道這個圖你們也看不明白,還是我來講吧!

具體的補位碼如下,"x"表示空位,用來補位的。

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

warning:有沒有發(fā)現(xiàn)?補位碼第一個字節(jié)前面有幾個1就表示整個UTF-8編碼占多少個字節(jié)!UTF-8解碼為Unicode就是利用的這個特點哦~

我們先舉個簡單的例子。把英文字母"A"轉(zhuǎn)為UTF8編碼。

1、“A”的charCode為65
2、65位于0-127的區(qū)間,所以“A”占一個字節(jié)
3、UTF8中一個字節(jié)的補位為0xxxxxxx,x表示的是空位,是用來補位的。
4、將65轉(zhuǎn)為二進(jìn)制得到1000001
5、將1000001按照從前到后的順序,依次補到1xxxxxxx的空位中,得到01000001
6、將11000001轉(zhuǎn)為字符串,得到"A"
7、最終,"A"為UTF8編碼之后“A”

通過這個小例子,我們是否再次驗證了UTF-8是Unicode的超集!

好了,我們現(xiàn)在再回到漢字"中"上,之前我們已經(jīng)得到了"中"的charCode為20013,二進(jìn)制為01001110 00101101。具體如下:

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

然后,我們按照上面“A”補位的方法,來給"中"補位。
將01001110 00101101按照從前到后的順序依此補位到1110xxxx 10xxxxxx 10xxxxxx上.得到11100100 10111000 10101101.

4、得到UTF8編碼的內(nèi)容

通過上面的步驟,我們得到了"中"的三個UTF8字節(jié),11100100 10111000 10101101。

我們將每個字節(jié)轉(zhuǎn)為16進(jìn)制,得到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>
// 最終得到三個字節(jié) 0xe4 0xb8 0xad

因為16進(jìn)制是不分大小寫的,所以是不是跟我們算出來0xE4 0xB8 0xAD一模一樣。

將上面的編碼邏輯寫到一個函數(shù)中。

// 將字符串格式化為UTF8編碼的字節(jié)
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字節(jié)的長度。因為長度為3,所以前兩個字節(jié)為`0,3`
// 內(nèi)容為`228, 184, 173`轉(zhuǎn)成16進(jìn)制就是`0xE4 0xB8 0xAD`
// 讀取UTF8編碼的字節(jié),并專為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字節(jié)碼的方法

另外一種比較簡單的將中文轉(zhuǎn)為UTF8字節(jié)碼的方法比較簡單,瀏覽器也提供了一個方法,而且這個方法大家都一直在用,是什么哪?就是encodeURI。當(dāng)然,encodeURIComponent也是可以的。

沒錯,就是這個方法。那么這個方法是怎么將一個Unicode編碼的中文轉(zhuǎn)為UTF8的字節(jié)碼嘞?

var str = '中';

var code = encodeURI(str);

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

有沒有發(fā)現(xiàn)得到了一個轉(zhuǎn)義后的字符串,而且這個字符串中的內(nèi)容和我之前在上面得到的字節(jié)碼是一樣的~~~。

下面我們將%E4%B8%AD轉(zhuǎn)為一個number數(shù)組。

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

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

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

如此簡單,有木有~~~

這個簡便方法的原理是什么?

這里就涉及到的URI中的querystring編碼的問題了。因為按照規(guī)定,URI中的querystring必須按照UTF8的編碼進(jìn)行傳輸,而JavaScript是Unicode的,所以瀏覽器就給我們提供了一個方法,也就是encodeURI/encodeURIComponent方法。這個方法會講
非英文字符(這里考慮下,為什么是非英文字符?)先轉(zhuǎn)為UTF8的字節(jié)碼,然后前面加個%進(jìn)行拼接,所以我們將漢字"中"轉(zhuǎn)義下便得到了"%E4%B8%AD".

好吧,原理就這些,沒有其他的了。

不過,這種方法還有個缺點,那就是只會轉(zhuǎn)義非英文字符,所以當(dāng)我們需要將英文字符也格式化為UTF8編碼時,這個方法是達(dá)不到我們需求的,我們還需要額外的將英文字符也給轉(zhuǎn)義下。

那我想要解析回來應(yīng)該怎么做哪?用decodeURI/decodeURIComponent就可以了。

var codeList = [228, 184, 173];

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

decodeURI(code); // => 中

好了,到這里本文也就介紹完UTF8的編碼了。
希望可以幫助大家了解到UTF-8編碼的原理。

以上就是小編為大家?guī)淼耐ㄟ^javascript進(jìn)行UTF-8編碼的實現(xiàn)方法全部內(nèi)容了,希望大家多多支持腳本之家~

相關(guān)文章

  • canvas 畫布在主流瀏覽器中的尺寸限制詳細(xì)介紹

    canvas 畫布在主流瀏覽器中的尺寸限制詳細(xì)介紹

    這篇文章主要介紹了canvas 畫布在主流瀏覽器中的尺寸限制詳細(xì)介紹的相關(guān)資料,canvas在不同瀏覽器下面有不同的最大尺寸限制,這里測試下,需要的朋友可以參考下
    2016-12-12
  • js實現(xiàn)提交前對列表數(shù)據(jù)的增刪改查

    js實現(xiàn)提交前對列表數(shù)據(jù)的增刪改查

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)提交前對列表數(shù)據(jù)的增刪改查,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • JavaScript組合拼接字符串的效率對比測試

    JavaScript組合拼接字符串的效率對比測試

    這篇文章主要介紹了JavaScript組合拼接字符串的效率對比測試,本文測試了IE6、Firefox、Mozilla、Netscape、Opera等瀏覽器,需要的朋友可以參考下
    2014-11-11
  • layui的table單擊行勾選checkbox功能方法

    layui的table單擊行勾選checkbox功能方法

    今天小編就為大家分享一篇layui的table單擊行勾選checkbox功能方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-08-08
  • js獲取元素的外鏈樣式的簡單實現(xiàn)方法

    js獲取元素的外鏈樣式的簡單實現(xiàn)方法

    下面小編就為大家?guī)硪黄猨s獲取元素的外鏈樣式的簡單實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • uniapp幾行代碼解決滾動穿透問題(項目實戰(zhàn))

    uniapp幾行代碼解決滾動穿透問題(項目實戰(zhàn))

    這篇文章主要介紹了uniapp幾行代碼解決滾動穿透問題,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01
  • Javascript類庫的頂層對象名用戶體驗分析

    Javascript類庫的頂層對象名用戶體驗分析

    針對jQuery、Ext、KISSY三者類庫的對比及分析已經(jīng)很多了,但多數(shù)是從功能和設(shè)計的角度切入,因此本篇文章決定換一個特殊的角度,從各類庫的頂層對象名的鍵盤輸入的體驗上來對這三個類庫進(jìn)行比較。
    2010-10-10
  • Bootstrap 3瀏覽器兼容性問題及解決方案

    Bootstrap 3瀏覽器兼容性問題及解決方案

    這篇文章主要為大家詳細(xì)介紹了 Bootstrap 3 瀏覽器兼容性問題及其對應(yīng)的解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • uniapp監(jiān)聽頁面滾動2種常用方法

    uniapp監(jiān)聽頁面滾動2種常用方法

    在uni-app中,監(jiān)聽頁面滾動可以使用onPageScroll生命周期函數(shù)或@scroll事件監(jiān)聽器,onPageScroll適用于監(jiān)聽整個頁面的滾動事件,而@scroll事件監(jiān)聽器適用于監(jiān)聽特定組件如scroll-view的滾動,這兩種方法的選擇取決于監(jiān)聽需求的不同,需要的朋友可以參考下
    2024-09-09
  • 微信小程序?qū)崿F(xiàn)簽字功能

    微信小程序?qū)崿F(xiàn)簽字功能

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)簽字功能,本文通過效果圖展示,實例代碼講解的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12

最新評論

比如县| 汝南县| 韩城市| 孝感市| 天全县| 龙州县| 芷江| 开原市| 丰城市| 贵定县| 迁安市| 凤山市| 新巴尔虎右旗| 义乌市| 古丈县| 万宁市| 济南市| 西乌珠穆沁旗| 保靖县| 天长市| 新巴尔虎右旗| 山东| 壤塘县| 江山市| 咸阳市| 武隆县| 广饶县| 康保县| 班戈县| 通州市| 大方县| 云梦县| 正定县| 津市市| 辽中县| 商丘市| 班玛县| 福州市| 黔西县| 阿克苏市| 罗源县|