node.js學(xué)習(xí)之base64編碼解碼
一. Base64編碼由來
為什么會(huì)有Base64編碼呢?因?yàn)橛行┚W(wǎng)絡(luò)傳送渠道并不支持所有的字節(jié),例如傳統(tǒng)的郵件只支持可見字符的傳送,像ASCII碼的控制字符就 不能通過郵件傳送。這樣用途就受到了很大的限制,比如圖片二進(jìn)制流的每個(gè)字節(jié)不可能全部是可見字符,所以就傳送不了。最好的方法就是在不改變傳統(tǒng)協(xié)議的情 況下,做一種擴(kuò)展方案來支持二進(jìn)制文件的傳送。把不可打印的字符也能用可打印字符來表示,問題就解決了。Base64編碼應(yīng)運(yùn)而生,Base64就是一種 基于64個(gè)可打印字符來表示二進(jìn)制數(shù)據(jù)的表示方法。
二. Base64編碼原理
看一下Base64的索引表,字符選用了"A-Z、a-z、0-9、+、/" 64個(gè)可打印字符。數(shù)值代表字符的索引,這個(gè)是標(biāo)準(zhǔn)Base64協(xié)議規(guī)定的,不能更改。64個(gè)字符用6個(gè)bit位就可以全部表示,一個(gè)字節(jié)有8個(gè)bit 位,剩下兩個(gè)bit就浪費(fèi)掉了,這樣就不得不犧牲一部分空間了。這里需要弄明白的就是一個(gè)Base64字符是8個(gè)bit,但是有效部分只有右邊的6個(gè) bit,左邊兩個(gè)永遠(yuǎn)是0。

那么怎么用6個(gè)有效bit來表示傳統(tǒng)字符的8個(gè)bit呢?8和6的最小公倍數(shù) 是24,也就是說3個(gè)傳統(tǒng)字節(jié)可以由4個(gè)Base64字符來表示,保證有效位數(shù)是一樣的,這樣就多了1/3的字節(jié)數(shù)來彌補(bǔ)Base64只有6個(gè)有效bit 的不足。你也可以說用兩個(gè)Base64字符也能表示一個(gè)傳統(tǒng)字符,但是采用最小公倍數(shù)的方案其實(shí)是最減少浪費(fèi)的。結(jié)合下邊的圖比較容易理解。Man是三個(gè) 字符,一共24個(gè)有效bit,只好用4個(gè)Base64字符來湊齊24個(gè)有效位。紅框表示的是對(duì)應(yīng)的Base64,6個(gè)有效位轉(zhuǎn)化成相應(yīng)的索引值再對(duì)應(yīng) Base64字符表,查出"Man"對(duì)應(yīng)的Base64字符是"TWFU"。說到這里有個(gè)原則不知道你發(fā)現(xiàn)了沒有,要轉(zhuǎn)換成Base64的最小單位就是三個(gè)字節(jié),對(duì)一個(gè)字符串來說每次都是三個(gè)字節(jié)三個(gè)字節(jié)的轉(zhuǎn)換,對(duì)應(yīng)的是Base64的四個(gè)字節(jié)。這個(gè)搞清楚了其實(shí)就差不多了。


但是轉(zhuǎn)換到最后你發(fā)現(xiàn)不夠三個(gè)字節(jié)了怎么辦呢?愿望終于實(shí)現(xiàn)了,我們可以用兩 個(gè)Base64來表示一個(gè)字符或用三個(gè)Base64表示兩個(gè)字符,像下圖的A對(duì)應(yīng)的第二個(gè)Base64的二進(jìn)制位只有兩個(gè),把后邊的四個(gè)補(bǔ)0就是了。所以 A對(duì)應(yīng)的Base64字符就是QQ。上邊已經(jīng)說過了,原則是Base64字符的最小單位是四個(gè)字符一組,那這才兩個(gè)字 符,后邊補(bǔ)兩個(gè)"="吧。其實(shí)不用"="也不耽誤解碼,之所以用"=",可能是考慮到多段編碼后的Base64字符串拼起來也不會(huì)引起混淆。由此可見 Base64字符串只可能最后出現(xiàn)一個(gè)或兩個(gè)"=",中間是不可能出現(xiàn)"="的。下圖中字符"BC"的編碼過程也是一樣的。

三、node.js普通字符串編碼解碼:
var b = new Buffer('JavaScript');
var s = b.toString('base64');
// SmF2YVNjcmlwdA==
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString();
// JavaScript
編碼解碼并轉(zhuǎn)成hex
var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
var s = b.toString('hex');
// 4a617661536372697074
var b = new Buffer('4a617661536372697074', 'hex')
var s = b.toString('utf8');
// JavaScript
四、node.js編碼解碼圖片
var fs = require('fs');
// function to encode file data to base64 encoded string
function base64_encode(file) {
// read binary data
var bitmap = fs.readFileSync(file);
// convert binary data to base64 encoded string
return new Buffer(bitmap).toString('base64');
}
// function to create file from base64 encoded string
function base64_decode(base64str, file) {
// create buffer object from base64 encoded string, it is important to tell the constructor that the string is base64 encoded
var bitmap = new Buffer(base64str, 'base64');
// write buffer to file
fs.writeFileSync(file, bitmap);
console.log('******** File created from base64 encoded string ********');
}
// convert image to base64 encoded string
var base64str = base64_encode('kitten.jpg');
console.log(base64str);
// convert base64 string back to image
base64_decode(base64str, 'copy.jpg');
總結(jié)
以上就是node.js之base64編碼解碼的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作帶來一定的幫助,如果有疑問大家可以留言交流。
相關(guān)文章
基于Node.js實(shí)現(xiàn)壓縮和解壓縮的方法
本篇文章主要介紹了基于Node.js實(shí)現(xiàn)壓縮和解壓縮的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02
Nodejs實(shí)戰(zhàn)心得之eventproxy模塊控制并發(fā)
本篇文章給大家分享我的nodejs實(shí)戰(zhàn)心得,如何使用eventproxy模塊控制并發(fā),感興趣的朋友可以參考下2015-10-10
async/await與promise(nodejs中的異步操作問題)
這篇文章主要介紹了async/await與promise(nodejs中的異步操作問題),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03
使用Nodejs開發(fā)微信公眾號(hào)后臺(tái)服務(wù)實(shí)例
這篇文章主要介紹了使用Nodejs開發(fā)微信公眾號(hào)后臺(tái)服務(wù)實(shí)例,在這個(gè)實(shí)例中,主要使用到了express, wechat, mongodb, monk等模塊,需要的朋友可以參考下2014-09-09
node.js 利用流實(shí)現(xiàn)讀寫同步,邊讀邊寫的方法
下面小編就為大家?guī)硪黄猲ode.js 利用流實(shí)現(xiàn)讀寫同步,邊讀邊寫的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09
NodeJS設(shè)計(jì)模式總結(jié)【單例模式,適配器模式,裝飾模式,觀察者模式】
這篇文章主要介紹了NodeJS設(shè)計(jì)模式,結(jié)合實(shí)例形式總結(jié)分析了nodejs單例模式,適配器模式,裝飾模式,觀察者模式的概念、原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-09-09

