Node.jsBuffer中的encoding的示例分析

這篇文章主要介紹了Node.js Buffer中的encoding的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)公司始終堅持【策劃先行,效果至上】的經(jīng)營理念,通過多達十多年累計超上千家客戶的網(wǎng)站建設(shè)總結(jié)了一套系統(tǒng)有效的全網(wǎng)營銷推廣解決方案,現(xiàn)已廣泛運用于各行各業(yè)的客戶,其中包括:成都混凝土泵車等企業(yè),備受客戶稱譽。

計算機最小的單位是一個位,也就是 0 和 1,在硬件上通過高低電平來對應。但是只有一位表示的信息太少了,所以又規(guī)定了 8 個位為一個字節(jié),之后數(shù)字、字符串等各種信息都是基于字節(jié)來存儲的。

字符怎么存儲呢?就是靠編碼,不同的字符對應不同的編碼,然后在需要渲染的時候根據(jù)對應編碼去查字體庫,然后渲染對應字符的圖形。

字符集

字符集(charset)最早是 ASCII 碼,也就是 abc ABC 123 等 128 個字符,因為計算機最早就是美國發(fā)明的。后來歐洲也制定了一套字符集標準,叫做 ISO,后來中國也搞了一套,叫做 GBK。

國際標準化組織覺得不能這樣各自搞一套,不然同一個編碼在不同字符集里面就不同的意思,于是就提出了 unicode 編碼,把全世界大部分編碼收錄,這樣每個字符只有唯一的編碼。

但是 ASCII 碼只需要 1 個字節(jié)就可以存儲,而 GBK 需要 2 個字節(jié),還有的字符集需要 3 個字節(jié)等,有的只要一個字節(jié)存儲卻存了 2 個字節(jié),比較浪費空間。所以就出現(xiàn)了 utf-8、utf-16、utf-24 等不同編碼方案。

utf-8、utf-16、utf-24 都是 unicode 編碼,但是具體實現(xiàn)方案不同。

UTF-8 為了節(jié)省空間,設(shè)計了從 1 到 6 個字節(jié)的變長存儲方案。而 UTF-16 是固定 2 個字節(jié),UTF-24 是固定 4 個字節(jié)。

Node.js Buffer中的encoding的示例分析

最后,UTF-8 因為占用空間最少,所以被廣泛應用。

Node.js 的 Buffer 的 encoding

每種語言都支持字符集的編碼解碼,Node.js 也同樣。

Node.js 里面可以通過 Buffer 來存儲二進制的數(shù)據(jù),而二進制的數(shù)據(jù)轉(zhuǎn)為字符串的時候就需要指定字符集,Buffer 的 from、byteLength、lastIndexOf 等方法都支持指定 encoding:

具體支持的 encoding 有這些:

utf8、ucs2、utf16le、latin1、ascii、base64、hex

可能有的同學會發(fā)現(xiàn): base64、hex 不是字符集啊,怎么也出現(xiàn)在這里?

是的,字節(jié)到字符的編碼方案除了字符集之外,也有用于轉(zhuǎn)為明文字符的 base64、以及轉(zhuǎn)為 16 進制的 hex。

這也是為什么 Node.js 把它叫做 encoding 而不是 charset,因為支持的編解碼方案不只是字符集。

如果不指定 encoding,默認是 utf8。

const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');

console.log(buf.toString());// hello world

encoding 的 源碼

我去翻了下 Node.js 關(guān)于 encoding 的源碼:

這一段是實現(xiàn) encoding 的:https://github.com/nodejs/node/blob/master/lib/buffer.js#L587-L726

可以看到每個 encoding 都實現(xiàn)了 encoding、encodingVal、byteLength、write、slice、indexOf 這幾個 api,因為這些 api 用不同 encoding 方案,會有不同的結(jié)果,Node.js 會根據(jù)傳入的 encoding 來返回不同的對象,這是一種多態(tài)的思想。

const encodingOps = {
  utf8: {
    encoding: 'utf8',
    encodingVal: encodingsMap.utf8,
    byteLength: byteLengthUtf8,
    write: (buf, string, offset, len) => buf.utf8Write(string, offset, len),
    slice: (buf, start, end) => buf.utf8Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf8, dir)
  },
  ucs2: {
    encoding: 'ucs2',
    encodingVal: encodingsMap.utf16le,
    byteLength: (string) => string.length * 2,
    write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len),
    slice: (buf, start, end) => buf.ucs2Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir)
  },
  utf16le: {
    encoding: 'utf16le',
    encodingVal: encodingsMap.utf16le,
    byteLength: (string) => string.length * 2,
    write: (buf, string, offset, len) => buf.ucs2Write(string, offset, len),
    slice: (buf, start, end) => buf.ucs2Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.utf16le, dir)
  },
  latin1: {
    encoding: 'latin1',
    encodingVal: encodingsMap.latin1,
    byteLength: (string) => string.length,
    write: (buf, string, offset, len) => buf.latin1Write(string, offset, len),
    slice: (buf, start, end) => buf.latin1Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfString(buf, val, byteOffset, encodingsMap.latin1, dir)
  },
  ascii: {
    encoding: 'ascii',
    encodingVal: encodingsMap.ascii,
    byteLength: (string) => string.length,
    write: (buf, string, offset, len) => buf.asciiWrite(string, offset, len),
    slice: (buf, start, end) => buf.asciiSlice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.ascii),
                    byteOffset,
                    encodingsMap.ascii,
                    dir)
  },
  base64: {
    encoding: 'base64',
    encodingVal: encodingsMap.base64,
    byteLength: (string) => base64ByteLength(string, string.length),
    write: (buf, string, offset, len) => buf.base64Write(string, offset, len),
    slice: (buf, start, end) => buf.base64Slice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.base64),
                    byteOffset,
                    encodingsMap.base64,
                    dir)
  },
  hex: {
    encoding: 'hex',
    encodingVal: encodingsMap.hex,
    byteLength: (string) => string.length >>> 1,
    write: (buf, string, offset, len) => buf.hexWrite(string, offset, len),
    slice: (buf, start, end) => buf.hexSlice(start, end),
    indexOf: (buf, val, byteOffset, dir) =>
      indexOfBuffer(buf,
                    fromStringFast(val, encodingOps.hex),
                    byteOffset,
                    encodingsMap.hex,
                    dir)
  }
};
function getEncodingOps(encoding) {
  encoding += '';
  switch (encoding.length) {
    case 4:
      if (encoding === 'utf8') return encodingOps.utf8;
      if (encoding === 'ucs2') return encodingOps.ucs2;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'utf8') return encodingOps.utf8;
      if (encoding === 'ucs2') return encodingOps.ucs2;
      break;
    case 5:
      if (encoding === 'utf-8') return encodingOps.utf8;
      if (encoding === 'ascii') return encodingOps.ascii;
      if (encoding === 'ucs-2') return encodingOps.ucs2;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'utf-8') return encodingOps.utf8;
      if (encoding === 'ascii') return encodingOps.ascii;
      if (encoding === 'ucs-2') return encodingOps.ucs2;
      break;
    case 7:
      if (encoding === 'utf16le' ||
          StringPrototypeToLowerCase(encoding) === 'utf16le')
        return encodingOps.utf16le;
      break;
    case 8:
      if (encoding === 'utf-16le' ||
          StringPrototypeToLowerCase(encoding) === 'utf-16le')
        return encodingOps.utf16le;
      break;
    case 6:
      if (encoding === 'latin1' || encoding === 'binary')
        return encodingOps.latin1;
      if (encoding === 'base64') return encodingOps.base64;
      encoding = StringPrototypeToLowerCase(encoding);
      if (encoding === 'latin1' || encoding === 'binary')
        return encodingOps.latin1;
      if (encoding === 'base64') return encodingOps.base64;
      break;
    case 3:
      if (encoding === 'hex' || StringPrototypeToLowerCase(encoding) === 'hex')
        return encodingOps.hex;
      break;
  }
}

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Node.js Buffer中的encoding的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學習!

文章題目:Node.jsBuffer中的encoding的示例分析
本文URL:http://muchs.cn/article36/iepcsg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣網(wǎng)站排名、微信小程序網(wǎng)站建設(shè)、外貿(mào)建站、網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)