Node中的字符編碼

unicode

首先搞清兩個(gè)概念,字符集編碼

  • 字符集:字符集是一張碼表,它規(guī)定了文字與數(shù)字的一一對(duì)應(yīng)關(guān)系。與計(jì)算機(jī)的內(nèi)部表示沒(méi)有必然的聯(lián)系。比如ASCII字符集,它規(guī)定了0~127這128個(gè)數(shù)字與哪些字符的對(duì)應(yīng)關(guān)系。常見(jiàn)的字符集包括:ASCII,GB2312,unicode等。
  • 編碼: 字符集是數(shù)字與字符對(duì)應(yīng)起來(lái)的方案,編碼則是在計(jì)算機(jī)與網(wǎng)絡(luò)中存儲(chǔ)、傳輸這些數(shù)字的方案。常見(jiàn)的編碼方式有utf8、utf16、GBK等。

unicode(統(tǒng)一碼、萬(wàn)國(guó)碼、單一碼、標(biāo)準(zhǔn)萬(wàn)國(guó)碼)是世界范圍內(nèi)通用的字符集,是一種標(biāo)準(zhǔn),它可以使電腦同時(shí)顯示世界上數(shù)十種文字。unicode編碼系統(tǒng)為表達(dá)任意語(yǔ)言的任意字符而設(shè)計(jì),使用4字節(jié)的數(shù)字來(lái)表達(dá)每個(gè)字母、符號(hào),或者表意文字。在unicode出現(xiàn)之前,世界各地都搞一套自己語(yǔ)音的字符集,混亂不堪,于是unicode組織就挺身而出,它們的目標(biāo)是囊括世界上所有的字符,同時(shí)解決歷史問(wèn)題,將既有的字符編碼方案以Unicode 編碼方案來(lái)加以取代。
歷史元老中,ASCII、GB2312是兼字符集與編碼方案為一身的,而unicode則是單純的字符集,它有多種編碼方案的實(shí)現(xiàn),如utf8、GBK等等。字符集和編碼的概念被徹底分離且模塊化的模型,其實(shí)是 Unicode 時(shí)代才得到廣泛認(rèn)同的。不同的編碼方案在存儲(chǔ)空間上各有長(zhǎng)處,有的存英文省,有的存中文省。

JavaScript的字符串是unicode字符串,內(nèi)部以utf-16編碼保存。
ES6中的String.prototype.codePointAt()方法可以得到指定字符的unicode碼點(diǎn)。
JavaScript中不存在gbk字符串、utf8字符串這樣的東西,但可以通過(guò)宿主環(huán)境或是第三方庫(kù)提供的轉(zhuǎn)碼方法,來(lái)將js字符串轉(zhuǎn)化為其他編碼,并用某種數(shù)據(jù)結(jié)構(gòu)(如瀏覽器中的ArrayBuffer,Node中的Buffer)來(lái)保存。

node支持的編碼類型

目前有:

  • ascii
  • base64
  • binary
  • hex
  • ucs2/ucs-2/utf16le/utf-16le
  • utf8/utf-8
  • latin1 (ISO8859-1, only in node 6.4.0+)

使用node的讀寫流時(shí),若data是string,則可以指定encoding參數(shù),以指定的編碼類型來(lái)讀寫字符串;若data是buffer,則忽略encoding參數(shù)。例如文件讀寫:

fs.writeFile('./xx.txt', '哈哈哈', 'utf8') // use string and encoding
fs.writeFile('./xx.txt', new Buffer('哈哈哈', 'utf8')) // use string
fs.readFile('./xx.txt', 'utf8', (err, data) => {...}) // data is a string
fs.readFile('./xx.txt', (err, data) => {...}) // data is a raw buffer

node中轉(zhuǎn)換字符編碼

node是不支持gbk、gb2312等上述以外編碼的,如果指定encoding為它們會(huì)報(bào)錯(cuò)Unknown encoding: xx。但可以通過(guò)第三方模塊iconv-lite來(lái)轉(zhuǎn)換編碼?;静僮魅缦拢?/p>

// 讀
const iconv = require('iconv-lite')
let data = fs.readFileSync('./xx.txt') // 假設(shè)txt是GB2312編碼的,data是一個(gè)buffer,存儲(chǔ)GB2312編碼的字符串?dāng)?shù)據(jù)
let str = iconv.decode(data, 'GB2312') // 將buffer解碼為string
// 拿到一個(gè)buffer欲將它轉(zhuǎn)為string,必須先知道它的編碼類型
// 寫
const str = '國(guó)慶節(jié)萬(wàn)歲'
let b = iconv.encode(str, 'GB2312') // b是一個(gè)buffer,存儲(chǔ)的是str的GB2312編碼的二進(jìn)制
fs.writeFile('./xx.txt', b) // 將str的GB2312編碼數(shù)據(jù)寫入到文件中

Base64/hex

Base64與hex都是將二進(jìn)制數(shù)據(jù)編碼成字符串的編碼方式,針對(duì)的是二進(jìn)制字節(jié)而非字符串。
因此,要獲得某個(gè)string的base64編碼時(shí),應(yīng)該先得到string的二進(jìn)制,再對(duì)二進(jìn)制進(jìn)行base6編碼:

// 編碼
const str = '哈哈'
let b = Buffer.from(str) // b中存的是哈哈的utf8編碼二進(jìn)制
let base64Code = b.toString('base64') // '5ZOI5ZOI'
// 解碼
const code = '5ZOI5ZOI'
let str = Buffer.from('5ZOI5ZOI', 'base64') // '哈哈'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容