什麼是 Base64 編碼?
Base64 編碼是一種將資料(通常是二進位制)轉換為 ASCII 字元集的方法。Base64 因為能夠起到隱藏資料的效果而常常被誤認為是一種加密技術。值得強調的是, Base64 不是一種加密或壓縮技術。實際上,Base64 編碼資訊的大小是原始資料實際大小的 1.3333 倍。
理解:假設我們有 6 個 ASCII 字元,那麼二進位制資料就是 6 * 8 = 48(位)。如果使用 Base64 編碼的話,那麼就會分成 48 / 6 = 8(組),每一組就會對應一個 ASCII 字元,也即是說,經過 Base64 編碼後,我們會有 8 個 ASCII 字元。因為資料傳輸的時候都會被轉換為電訊號(雖然你看到的是字元),所以資料的大小都是按位元來算的,8 個 ASCII 字元就是 8 * 8 = 64(位),64 / 48 = 4 / 3 ≈ 1.3333 。 綜上所述,Base64 編碼資訊的大小是原始資料實際大小的 1.3333 倍。
Base64 是使用最廣泛的基本編碼技術,另外兩種常用的編碼方案是 Base16 和 Base32。
Base64 是如何工作的?
將資料轉換為 base64 是一個多步驟的過程。以下是它對文字字串的工作方式:
為了更好地理解這個概念,讓我們看一個例子。假設我們有字串「Go win」,我們想將其轉換為 Base64 字串。第一步是將此字串轉換為二進位制。 「Go win」的二進位制版本是:
01000111 01101111 00100000 01110111 01101001 01101110
您可以在此處看到每個字元由 8 位表示。然而,正如我們之前所說,Base64 將 8 位二進位制為一組形式的資料轉換為 6 位為一組形式的資料。這是因為 Base64 格式只有 64 個字元:26 個大寫字母、26 個小寫字母、10 個數位字元以及用於換行的「+」和「/」符號。
Base64 不使用所有的 ASCII 特殊字元,而只使用這幾個。請注意,Base64 的某些實現使用與「+」和「/」不同的特殊字元。
回到這個例子,讓我們將 8 位資料分成 6 位為一組。
010001 110110 111100 100000 011101 110110 100101 101110
您不會總是能夠將資料分成完整的 6 位集,在這種情況下,您將不得不手動填充 0 。
現在對於上面的每個塊,我們必須找到它的十進位制值。下面給出了這些十進位制值:
Binary Decimal 010001 17 110110 54 111100 60 100000 32 011101 29 110110 54 100101 37 101110 46
最後,我們必須檢視我們剛剛從二進位制資料計算出的每個十進位制數的 Base64 值。 Base64 編碼表如下所示:
在這裡你可以看到十進位制的 17 對應於「R」,十進位制的 54 對應於「2」,依此類推。使用此編碼表,我們可以看到字串「Go win」使用 Base64 編碼為「R28gd2lu」。您可以使用任何線上文字轉 Base64 轉換器來驗證此結果。
為什麼要使用 Base64 編碼?
以二進位制格式傳送資訊有時會有風險,因為並非所有應用程式或網路系統都可以處理原始二進位制檔案。另一方面,ASCII 字元集廣為人知,並且對於大多數系統來說處理起來非常簡單。
例如,電子郵件伺服器需要文字資料,因此通常使用 ASCII。因此,如果您想將圖片或任何其他二進位制檔案傳送到電子郵件伺服器,您首先需要將其編碼為基於文字的格式,最好是 ASCII。這就是 Base64 編碼在將二進位制資料轉換為正確格式方面非常方便的地方。
使用 Node.js 對字串進行 Base64 編碼
在 Node.js 中對 Base64 字串進行編碼的最簡單方法是通過 Buffer 物件。在 Node.js 中,Buffer 是一個全域性物件,這意味著你不需要使用 require 語句匯入應用程式就可以使用 Buffer 物件。
在實體記憶體中,緩衝區是一個不可變的整數陣列,它也能夠執行許多不同的編碼/解碼。這些包括到從 UTF-8、UCS2、Base64 和 十六進位制編碼到另外一種格式, 或者從另外一種格式編碼到 UTF-8、UCS2、Base64 和 十六進位制。當您編寫處理和運算元據的程式碼時,您可能會在某個時候使用 Buffer 物件。
看看下面的例子。在這裡,我們將使用 Buffer 物件將文字字串編碼為 Base64。將以下程式碼儲存在「encode-text.js」檔案中:
'use strict'; let data = 'stackabuse.com'; let buff = new Buffer(data); // 預設用 utf-8 編碼格式解釋字串 let base64data = buff.toString('base64'); console.log('"' + data + '" converted to Base64 is "' + base64data + '"');
在上面的指令碼中,我們建立了一個新的緩衝區物件並將我們想要轉換為 Base64 的字串傳遞給它。然後我們在剛剛建立的緩衝區物件上呼叫「toString」方法,並將「base64」作為引數傳遞給它。以「base64」為引數的「toString」方法將以 Base64 字串的形式返回資料。執行上面的程式碼,你會看到下面的輸出。
$ node encode-text.js "stackabuse.com" converted to Base64 is "c3RhY2thYnVzZS5jb20="
在輸出中,我們可以看到轉換為 Base64 的字串和它的原始資料。
使用 Node.js 解碼 Base64 字串
解碼 Base64 字串與編碼非常相似。您必須建立一個新的緩衝區物件並將兩個引數傳遞給它的建構函式。第一個引數是 Base64 中的資料,第二個引數是「base64」。然後您只需在緩衝區物件上呼叫「toString」,但這次傳遞給該方法的引數將是「ascii」,因為這是您希望 Base64 資料轉換為的資料型別。請檢視以下程式碼片段以供參考。
'use strict'; let data = 'Tm8gdG8gUmFjaXNt'; let buff = new Buffer(data, 'base64'); let text = buff.toString('ascii'); console.log('"' + data + '" converted from Base64 to ASCII is "' + text + '"');
將資料新增到 「ascii.js」 檔案並儲存。這裡我們使用了「Tm8gdG8gUmFjaXNt」作為 Base64 輸入資料。當這些資料被解碼時,它應該顯示「No to Racism」。
將二進位制資料編碼為 Base64 字串
正如文章開頭提到的,Base64 編碼的主要目的是將二進位制資料轉換為文字格式。讓我們看一個範例,我們將影象(二進位制資料)轉換為 Base64 字串。看看下面的例子。
'use strict'; const fs = require('fs'); let buff = fs.readFileSync('stack-abuse-logo.png'); let base64data = buff.toString('base64'); console.log('Image converted to base 64 is:\n\n' + base64data);
在上面的程式碼中,我們通過 fs 模組的 readFileSync() 方法將影象載入到緩衝區中。該過程的其餘部分類似於從普通 ASCII 字串建立 Base64 字串。
當您執行上面的程式碼時,您將看到以下輸出。
$ node encode-image.js Image converted to Base64 is: iVBORw0KGgoAAAANSUhEUgAAABkAAAATCAYAAABlcqYFAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAADuUlEQVQ4EbVUTUtcZxR+7ufkXp1SZ4iZRE1EDVQRnTAhowsZMFm40I2rNqUIIev8hvoPQroQXBTqwiAWcd0EglEhiZNajVZrQGXAWAzaZpzMnZn7lXPeeIe5DaWb9Ax33vOec8/znI/3vVI6nfbxP4v8b/iSJIGfzyGfkPi+D13XUalUBL6qqmIvy5+8WuX/r2RCkUzAoIuLi2hqaoLrutjb28P6+josyxJkiqJA07SQXiqVwHaOZYx/itLc3Px9YIxEIlheXsbExATGxsYwMjIiwEdHRwXA/Pw8EokEcrkcDg4OYJomVlZWMDU1JSqfmZlBR0cHbNsOtVoNCHjlTFiSySQMwxAVxONxQbi0tIRMJoPe3l5MT0+jtbUVg4ODYGImY18qlcL4+DhisZjoggCjv1C7uOyenh7Mzs5iY2ND6FQpdnd3sba2JloSjUYxPDyM/v5+TE5OYn9/X9jZtrOzg+3t7WqyAUmoEu419/+HBw9E+eVymbJqAJP39fWBCR3HEU+hUMDQ0JCYGc8um81iYGAAjY2N8DwvwBdraCY8tHhDA1Y3N9Hd3S2yvH37O7RcbsF7AuUsD9+8wdOFBTx/8QJtbW1C5/nMzc3R0D2UyxXk83lRXcAk1V5GCT5sSUGDbeHxy9/EO98M9OOXzT9wfHISxKC1vR0GHfOtrS2g/SouWwU0Xkggu7qO9PUkJFULnbIQyTm6ewu2hF+vnOIIUQwdGlg8f4QF6wvMWBq+pAkaskSnx4FFVUf0CNpcC797KizXQ4oAHhVdXJJ81F7j6kwUynPHlXDPdFB2fRj+KVK0KvT2rbp3uKYryJU11Cke8qqMuOoioeeJ1MPDYxM36m1cNSq4GdFx58RAWvbx8TrXnK4IgR16Em5GK4iqHi5GHHxLgcSDn97WgZPoND+GGZRpPYH85cgiiRQl1ltXxmFFQ5PuopP8TrW5ZyRcWp7AbmkeZefg5+N6PPnbRJdpw/YlfB0vQiPQZwVdZNtFZEVK6D1VTnccJlXzuqTjvOZiq6Rhj2KqLSJsofOHgIl8+t0/qsfDioxmSUWGjrRFzhYi/5Oynrdl3KXHIZDXtF6hil8R6I9FBV/RvDLnXKxSbAdVYhNeINXBMwmXWCTQGG2Y+Jj+dFrfEmiMAtmeowpo9ojTvkD+A/L1UJUMmiVfkuz6WTyZhFRJAgP33j3bsM5k/Fng68UP21hYJyyxZwLWuS2cKMfUSm3rhD0g4E2g197fwMZ+Bgt8rNe2iP2BhL5dgfFzrx8AfECEDdx45a0AAAAASUVORK5CYII=
雖然實際影象非常小(25x19),但輸出仍然相當大,部分原因是 Base64 增加了資料的大小,正如我們之前提到的。
將 Base64 字串解碼為二進位制資料
這裡的反向過程與我們在前面部分中看到的解碼 Base64 字串的方式非常相似。最大的區別是輸出目的地以及資料在那裡寫入的方式。讓我們看看這個例子:
'use strict'; const fs = require('fs'); let buff = new Buffer(data, 'base64'); fs.writeFileSync('stack-abuse-logo-out.png', buff); let data = 'iVBORw0KGgoAAAANSUhEUgAAABkAAAATCAYAAABlcqYFAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAA' + 'CA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAACXBIWXMAAAsTAAALEwEAmpwYAAABWWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0' + 'YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly' + '93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAg' + 'ICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZm' + 'Y6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpMwidZAAADuUlEQVQ4EbVU' + 'TUtcZxR+7ufkXp1SZ4iZRE1EDVQRnTAhowsZMFm40I2rNqUIIev8hvoPQroQXBTqwiAWcd0EglEhiZNajVZrQGXAWAzaZpzMnZn7lXPeeIe5Da' + 'Wb9Ax33vOec8/znI/3vVI6nfbxP4v8b/iSJIGfzyGfkPi+D13XUalUBL6qqmIvy5+8WuX/r2RCkUzAoIuLi2hqaoLrutjb28P6+josyxJkiqJA' + '07SQXiqVwHaOZYx/itLc3Px9YIxEIlheXsbExATGxsYwMjIiwEdHRwXA/Pw8EokEcrkcDg4OYJomVlZWMDU1JSqfmZlBR0cHbNsOtVoNCHjlTF' + 'iSySQMwxAVxONxQbi0tIRMJoPe3l5MT0+jtbUVg4ODYGImY18qlcL4+DhisZjoggCjv1C7uOyenh7Mzs5iY2ND6FQpdnd3sba2JloSjUYxPDyM' + '/v5+TE5OYn9/X9jZtrOzg+3t7WqyAUmoEu419/+HBw9E+eVymbJqAJP39fWBCR3HEU+hUMDQ0JCYGc8um81iYGAAjY2N8DwvwBdraCY8tHhDA1' + 'Y3N9Hd3S2yvH37O7RcbsF7AuUsD9+8wdOFBTx/8QJtbW1C5/nMzc3R0D2UyxXk83lRXcAk1V5GCT5sSUGDbeHxy9/EO98M9OOXzT9wfHISxKC1' + 'vR0GHfOtrS2g/SouWwU0Xkggu7qO9PUkJFULnbIQyTm6ewu2hF+vnOIIUQwdGlg8f4QF6wvMWBq+pAkaskSnx4FFVUf0CNpcC797KizXQ4oAHh' + 'VdXJJ81F7j6kwUynPHlXDPdFB2fRj+KVK0KvT2rbp3uKYryJU11Cke8qqMuOoioeeJ1MPDYxM36m1cNSq4GdFx58RAWvbx8TrXnK4IgR16Em5G' + 'K4iqHi5GHHxLgcSDn97WgZPoND+GGZRpPYH85cgiiRQl1ltXxmFFQ5PuopP8TrW5ZyRcWp7AbmkeZefg5+N6PPnbRJdpw/YlfB0vQiPQZwVdZN' + 'tFZEVK6D1VTnccJlXzuqTjvOZiq6Rhj2KqLSJsofOHgIl8+t0/qsfDioxmSUWGjrRFzhYi/5Oynrdl3KXHIZDXtF6hil8R6I9FBV/RvDLnXKxS' + 'bAdVYhNeINXBMwmXWCTQGG2Y+Jj+dFrfEmiMAtmeowpo9ojTvkD+A/L1UJUMmiVfkuz6WTyZhFRJAgP33j3bsM5k/Fng68UP21hYJyyxZwLWuS' + '2cKMfUSm3rhD0g4E2g197fwMZ+Bgt8rNe2iP2BhL5dgfFzrx8AfECEDdx45a0AAAAASUVORK5CYII='; console.log('Base64 image data converted to file: stack-abuse-logo-out.png');
在這裡您可以看到我們從 Base64 資料(也可以從 socket 或其他一些通訊線路接收)開始,然後將其載入到 Buffer 物件中。在建立緩衝區時,我們告訴它它是 base64 格式,這允許緩衝區相應地解析它以進行內部儲存。
要將資料儲存回原始 PNG 格式,我們只需將 Buffer 物件傳遞給我們的 fs.writeFileSync 方法,它就會為我們進行轉換。
結論
Base64 編碼是將二進位制資料轉換為純 ASCII 文字的最常用方法之一。它是一種非常有用的格式,用於在一個或多個無法輕鬆處理二進位制資料的系統之間進行通訊,例如 HTML 標記中的影象或 Web 請求。
在 Node.js 中,我們可以通過 Buffer 物件來輕鬆完成 Base64 字串與許多其他格式資料相互轉換的工作。
英文原文地址:https://stackabuse.com/encoding-and-decoding-base64-strings-in-node-js/
更多程式設計相關知識,請存取:!!
以上就是淺談nodejs中怎麼對字串進行Base64編碼和解碼的詳細內容,更多請關注TW511.COM其它相關文章!