關于base64編碼的原理及實現

我們的圖片大部分都是可以轉換成base64編碼的data:image。 這個在將canvas保存為img的時候尤其有用。雖然除ie外,大部分現代瀏覽器都已經支持原生的基于base64的encode和decode,例如btoa和atob。(將canvas畫布保存成img并強制改變mimetype進行下載,會在下一篇記錄)

但是處于好奇心,還是驅使我去了解下base64編碼的原理。以便也在不支持原生base64編碼的ie下可以得以實現。

【Base64】
-base64的編碼都是按字符串長度,以每3個8bit的字符為一組,
-然后針對每組,首先獲取每個字符的ASCII編碼,
-然后將ASCII編碼轉換成8bit的二進制,得到一組3*8=24bit的字節
-然后再將這24bit劃分為4個6bit的字節,并在每個6bit的字節前面都填兩個高位0,得到4個8bit的字節
-然后將這4個8bit的字節轉換成10進制,對照Base64編碼表 (下表),得到對應編碼后的字符。

(注:1. 要求被編碼字符是8bit的,所以須在ASCII編碼范圍內,\u0000-\u00ff,中文就不行。
   2. 如果被編碼字符長度不是3的倍數的時候,則都用0代替,對應的輸出字符為=)

Base64 編碼表
ValueChar?ValueChar?ValueChar?ValueChar
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

比如舉下面2個例子:
a) 字符長度為能被3整除時:比如“Tom” :

            T           o           m
ASCII: 84 111 109
8bit字節: 01010100 01101111 01101101
6bit字節: 010101 000110 111101 101101
十進制: 21 6 61 45
對應編碼: V G 9 t

所以,btoa('Tom') = VG9t

b) 字符串長度不能被3整除時,比如“Lucy”:

            L           u           c           y
ASCII: 76 117 99 121
8bit字節: 01001100 01110101 01100011 01111001 00000000 00000000
6bit字節: 010011 000111 010101 100011 011110 010000 000000 000000
十進制: 19 7 21 35 30 16 (異常) (異常)
對應編碼: T H V j e Q = =

由于Lucy只有4個字母,所以按3個一組的話,第二組還有兩個空位,所以需要用0來補齊。這里就需要注意,因為是需要補齊而出現的0,所以轉化成十進制的時候就不能按常規用base64編碼表來對應,所以不是a, 可以理解成為一種特殊的“異常”,編碼應該對應“=”。

有了上面的理論,那我們實現一個base64編碼就容易了。
?

/**
* base64 encoding & decoding
* for fixing browsers which don't support Base64 | btoa |atob
*/

(function (win, undefined) {

var Base64 = function () {
var base64hash = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

// btoa method
function _btoa (s) {
if (/([^\u0000-\u00ff])/.test(s)) {
throw new Error('INVALID_CHARACTER_ERR');
}
var i = 0,
prev,
ascii,
mod,
result = [];

while (i < s.length) {
ascii = s.charCodeAt(i);
mod = i % 3;

switch(mod) {
// 第一個6位只需要讓8位二進制右移兩位
case 0:
result.push(base64hash.charAt(ascii >> 2));
break;
//第二個6位 = 第一個8位的后兩位 + 第二個8位的前4位
case 1:
result.push(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)));
break;
//第三個6位 = 第二個8位的后4位 + 第三個8位的前2位
//第4個6位 = 第三個8位的后6位
case 2:
result.push(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)));
result.push(base64hash.charAt(ascii & 0x3f));
break;
}

prev = ascii;
i ++;
}

// 循環結束后看mod, 為0 證明需補3個6位,第一個為最后一個8位的最后兩位后面補4個0。另外兩個6位對應的是異常的“=”;
// mod為1,證明還需補兩個6位,一個是最后一個8位的后4位補兩個0,另一個對應異常的“=”
if(mod == 0) {
result.push(base64hash.charAt((prev & 3) << 4));
result.push('==');
} else if (mod == 1) {
result.push(base64hash.charAt((prev & 0x0f) << 2));
result.push('=');
}

return result.join('');
}

// atob method
// 逆轉encode的思路即可
function _atob (s) {
s = s.replace(/\s|=/g, '');
var cur,
prev,
mod,
i = 0,
result = [];

while (i < s.length) {
cur = base64hash.indexOf(s.charAt(i));
mod = i % 4;

switch (mod) {
case 0:
//TODO
break;
case 1:
result.push(String.fromCharCode(prev << 2 | cur >> 4));
break;
case 2:
result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
break;
case 3:
result.push(String.fromCharCode((prev & 3) << 6 | cur));
break;

}

prev = cur;
i ++;
}

return result.join('');
}

return {
btoa: _btoa,
atob: _atob,
encode: _btoa,
decode: _atob
};
}();

if (!win.Base64) { win.Base64 = Base64 }
if (!win.btoa) { win.btoa = Base64.btoa }
if (!win.atob) { win.atob = Base64.atob }

})(window)

?

Base64 example

?

轉載于:https://www.cnblogs.com/hongru/archive/2012/01/14/2321397.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275067.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275067.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275067.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Django web開發系列(五)模板

一 前言在上一節了解到視圖函數處理后&#xff0c;會將結果渲染到創建的html頁面&#xff0c;但html如何接收并顯示視圖函數返回的動態數據呢&#xff1f;最常用的做法就是使用模板(Template)&#xff0c;本節將簡單介紹一下模板的作用和用法。 可以這樣簡單的理解模板的概念&a…

facebook 面試_如何為您的Facebook產品設計面試做準備

facebook 面試重點 (Top highlight)Last month, I joined Facebook to work on Instagram DMs and as a way to pay it forward, I 上個月&#xff0c;我加入了Facebook&#xff0c;從事Instagram DM的工作&#xff0c;作為一種支付方式&#xff0c;我 offered to help anyone…

8年了,開始寫點東西了

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。今天分享一位大佬的文章…

荒徑 弗羅斯特_弗羅斯特龐克,顛覆性城市建設者

荒徑 弗羅斯特Most gamers are familiar with Will Wright’s famous SimCity series. It created the city building genre and there have been many attempts over the years to ape it. But few developers have been bold enough to completely deconstruct the formula; …

2012年1月份第2周51Aspx源碼發布詳情

WP7手指畫圖應用源碼 2012-01-14 [VS2010] 游戲介紹&#xff1a;Windows Phone 7手指畫圖應用 – FingerPaint&#xff0c;您通過此游戲可以隨心畫一些感興趣的東西&#xff0c;陶冶情操。操作簡單&#xff0c;頁面簡潔。適合新手學習參考。 WP7 Car Bloke(交通工具開銷記錄)源…

Gitee 如何自動部署博客 Pages?推薦用這個GitHub Actions!

大家好&#xff0c;我是若川。最近組織了源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。前段時間我把自己的博客…

Java io流學習總結(三)

轉載于&#xff1a;https://www.cnblogs.com/ll409546297/p/7197911.html java.io幾種讀寫文件的方式 一、Java把這些不同來源和目標的數據都統一抽象為數據流。 Java語言的輸入輸出功能是十分強大而靈活的。 在Java類庫中&#xff0c;IO部分的內容是很龐大的&#xff0c;因為它…

現在流行的畫原型圖工具_原型資源圖:8種流行原型工具的綜合指南

現在流行的畫原型圖工具Although tools are not the most important things to learn as a UX designer, inevitably you need to use it in order to achieve your more important goals, to solve user’s problems. This article covers today’s 8 popular UX prototyping …

持續5個月,200+筆記,3千多人參與,邀請你來學源碼~

注意&#xff1a;本文點擊文末閱讀原文可查看文中所有鏈接。我正在參加掘金年度人氣作者投票活動&#xff0c;大家有空可以加微信群幫忙投票&#xff0c;感謝大家&#xff01;想起今天還沒發文&#xff0c;就開放下微信群二維碼&#xff0c;大家掃碼進群讀源碼和幫忙投票吧。群…

自己動手開發調試器 01

背景: 在做XXX編譯器檢證時經常需要區分是代碼端錯誤&#xff0c;還是編譯器端錯誤&#xff0c;因此對代碼進行調試是必不可少的。但是狗日的甲方并沒有提供對應的調試器XXXDB&#xff0c;而用GDB調試XXX生成的可執行程序很不穩定&#xff0c;經常出現異常&#xff0c;干脆…

02如何抓住重點,系統高效地學習數據結構與算法?

以下內容總結自極客時間王爭大佬的《數據結構與算法之美》課程&#xff0c;本文章僅供個人學習總結。 什么是數據結構?什么是算法? 從廣義上講&#xff0c;數據結構就是指一組數據的存儲結構。算法就是操作數據的一組方法。 類比圖書館的書籍&#xff0c;我們如果想找一本書可…

第2年,倒數第3天,1.5萬票,感動!

1源碼共讀大家好&#xff0c;我是若川。眾所周知。從8月份開始&#xff0c;我組織了源碼共讀活動&#xff0c;至今已經有5個月了&#xff0c;每周一期&#xff0c;進行到了第18期。每周堅持寫源碼解讀文章&#xff0c;每天堅持答疑解惑&#xff0c;幫助了很多人學會看源碼&…

啟發式搜索給神經網絡_神經科學如何支持UX啟發式

啟發式搜索給神經網絡重點 (Top highlight)Interaction and UX designers have long known and used heuristics to guide the creation of a user-friendly interface. We know empirically that these principles work, and they make “common sense”. These heuristics th…

Django實戰(1):需求分析和設計

Depot是《Agile Web Development with Rails》中的一個購物車應用。 該書中用多次迭代的方法&#xff0c;逐步實現購物車應用&#xff0c;使很多人走上了rails開發的道路。 遺憾的是Django世界中好像沒有類似的指引&#xff0c;也許是因為pythoner 不需要具體的例子。 但是如果…

使用 apiDoc 為你的Node.js API 生成文檔

翻譯&#xff1a; 瘋狂的技術宅 原文&#xff1a;jonathas.com/documenting… 未經許可&#xff0c;禁止轉載&#xff01; 當你為其他開發人員&#xff08;前端&#xff0c;桌面&#xff0c;移動等&#xff09;開發 API 時&#xff0c;需要生成一份風格良好的文檔&#xff0c;以…

海浪 shader_海浪下的發現

海浪 shaderI’ve been playing Subnautica for over 25 hours now, and likely have at least that many more to go. The game puts you in the shoes of a crew member on the Aurora, a spaceship that suffers a catastrophic incident and plummets to the largely ocean…

最后一天,特邀小姐姐配音拉票,今日可投28票

1源碼共讀大家好&#xff0c;我是若川。最后一天&#xff0c;特邀小姐姐配音拉票&#xff0c;超級好聽。眾所周知。從8月份開始&#xff0c;我組織了源碼共讀活動&#xff0c;至今已經有5個月了&#xff0c;每周一期&#xff0c;進行到了第18期。每周堅持寫源碼解讀文章&#x…

NET中使用Memcached的相關資源整理

本文轉自&#xff1a;http://www.cnblogs.com/dudu/archive/2009/07/19/1526407.html Memcached官方站點&#xff1a;http://www.danga.com/memcached / Memcached Win32 1.2.6下載&#xff1a;http://code.jellycan.com/memcached/ 安裝幫助&#xff1a;Windows下的.NET Memca…

FFMPEG 視頻圖像解封裝解碼

FFMPEG4.0 音頻解碼解封裝FFMPEG 音頻封裝編碼 下面的函數方法基于最新的FFMPEG 4.0&#xff08;4.X&#xff09;&#xff1a;本文講是如何從一個視頻文件中提取出其中的圖像數據&#xff0c;并將圖像數據保存到文件中。 解碼解封裝的過程與音頻差不多&#xff0c;具體如下&…

對數據可視化的理解_使數據可視化更容易理解

對數據可視化的理解Data is weaving its way into almost all aspects of our lives since the past decade. Our ability to store more information in smaller and smaller spaces has encouraged us to make sure we leave no information out. The ease of collecting inf…