您好,登錄后才能下訂單哦!
這篇文章主要介紹了Node.js Buffer中的encoding的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
計(jì)算機(jī)最小的單位是一個(gè)位,也就是 0 和 1,在硬件上通過高低電平來對(duì)應(yīng)。但是只有一位表示的信息太少了,所以又規(guī)定了 8 個(gè)位為一個(gè)字節(jié),之后數(shù)字、字符串等各種信息都是基于字節(jié)來存儲(chǔ)的。
字符怎么存儲(chǔ)呢?就是靠編碼,不同的字符對(duì)應(yīng)不同的編碼,然后在需要渲染的時(shí)候根據(jù)對(duì)應(yīng)編碼去查字體庫,然后渲染對(duì)應(yīng)字符的圖形。
字符集(charset)最早是 ASCII 碼,也就是 abc ABC 123 等 128 個(gè)字符,因?yàn)橛?jì)算機(jī)最早就是美國發(fā)明的。后來歐洲也制定了一套字符集標(biāo)準(zhǔn),叫做 ISO,后來中國也搞了一套,叫做 GBK。
國際標(biāo)準(zhǔn)化組織覺得不能這樣各自搞一套,不然同一個(gè)編碼在不同字符集里面就不同的意思,于是就提出了 unicode 編碼,把全世界大部分編碼收錄,這樣每個(gè)字符只有唯一的編碼。
但是 ASCII 碼只需要 1 個(gè)字節(jié)就可以存儲(chǔ),而 GBK 需要 2 個(gè)字節(jié),還有的字符集需要 3 個(gè)字節(jié)等,有的只要一個(gè)字節(jié)存儲(chǔ)卻存了 2 個(gè)字節(jié),比較浪費(fèi)空間。所以就出現(xiàn)了 utf-8、utf-16、utf-24 等不同編碼方案。
utf-8、utf-16、utf-24 都是 unicode 編碼,但是具體實(shí)現(xiàn)方案不同。
UTF-8 為了節(jié)省空間,設(shè)計(jì)了從 1 到 6 個(gè)字節(jié)的變長存儲(chǔ)方案。而 UTF-16 是固定 2 個(gè)字節(jié),UTF-24 是固定 4 個(gè)字節(jié)。
最后,UTF-8 因?yàn)檎加每臻g最少,所以被廣泛應(yīng)用。
每種語言都支持字符集的編碼解碼,Node.js 也同樣。
Node.js 里面可以通過 Buffer 來存儲(chǔ)二進(jìn)制的數(shù)據(jù),而二進(jìn)制的數(shù)據(jù)轉(zhuǎn)為字符串的時(shí)候就需要指定字符集,Buffer 的 from、byteLength、lastIndexOf 等方法都支持指定 encoding:
具體支持的 encoding 有這些:
utf8、ucs2、utf16le、latin1、ascii、base64、hex
可能有的同學(xué)會(huì)發(fā)現(xiàn): base64、hex 不是字符集啊,怎么也出現(xiàn)在這里?
是的,字節(jié)到字符的編碼方案除了字符集之外,也有用于轉(zhuǎn)為明文字符的 base64、以及轉(zhuǎn)為 16 進(jìn)制的 hex。
這也是為什么 Node.js 把它叫做 encoding 而不是 charset,因?yàn)橹С值木幗獯a方案不只是字符集。
如果不指定 encoding,默認(rèn)是 utf8。
const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64'); console.log(buf.toString());// hello world
我去翻了下 Node.js 關(guān)于 encoding 的源碼:
這一段是實(shí)現(xiàn) encoding 的:https://github.com/nodejs/node/blob/master/lib/buffer.js#L587-L726
可以看到每個(gè) encoding 都實(shí)現(xiàn)了 encoding、encodingVal、byteLength、write、slice、indexOf 這幾個(gè) api,因?yàn)檫@些 api 用不同 encoding 方案,會(huì)有不同的結(jié)果,Node.js 會(huì)根據(jù)傳入的 encoding 來返回不同的對(duì)象,這是一種多態(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; } }
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Node.js Buffer中的encoding的示例分析”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。