JavaScript實現Base64

来源:http://www.cnblogs.com/laixiangran/archive/2016/04/22/5423157.html
-Advertisement-
Play Games

簡介 Base64是一種基於64個可列印字元來表示二進位數據的表示方法。由於2的6次方等於64,所以每6個比特為一個單元,對應某個可列印字元。三個位元組有24個比特,對應於4個Base64單元,即3個位元組需要用4個可列印字元來表示。它可用來作為電子郵件的傳輸編碼。在Base64中的可列印字元包括字母A ...


簡介

Base64是一種基於64個可列印字元來表示二進位數據的表示方法。由於2的6次方等於64,所以每6個比特為一個單元,對應某個可列印字元。三個位元組有24個比特,對應於4個Base64單元,即3個位元組需要用4個可列印字元來表示。它可用來作為電子郵件的傳輸編碼。在Base64中的可列印字元包括字母A-Z、a-z、數字0-9,這樣共有62個字元,此外的兩個可列印符號在不同的系統中而不同,一般為+和/。

轉換原理

Base64的直接數據源是二進位序列(Binary Sequence)。當然,你也可以將圖片、文本和音視頻轉換成二進位序列,再然後轉換為Base64編碼。我們這裡討論的是如何將二進位轉換為Base64編碼,對於如何將圖片,文本和音視頻轉換為二進位序列敬請期待。

在轉換前,先定義一張索引表,這張表規定瞭如何轉換:

image

轉換的時候我們先將二進位序列分組,每6個比特為一組。但是如果編碼的位元組數不能被3整除,那麼最後就會多出1個或兩個位元組,可以使用下麵的方法進行處理:先使用0位元組值在末尾補足,使其能夠被3整除,然後再進行base64的編碼。在編碼後的base64文本後加上一個或兩個’=’號,代表補足的位元組數。也就是說,當最後剩餘一個八位位元組(一個byte)時,最後一個6位的base64位元組塊有四位是0值,最後附加上兩個等號;如果最後剩餘兩個八位位元組(2個byte)時,最後一個6位的base位元組塊有兩位是0值,最後附加一個等號。 參考下表:

image

JavaScript實現Base64

原理明白了以後,實現起來就很容易了。

define(function(require, exports, module) {
 
    var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""); //索引表
 
    /**
     * @author laixiangran@163.com
     * @description 將二進位序列轉換為Base64編碼
     * @param  {String}
     * @return {String}
     */
    function binToBase64(bitString) {
        var result = "";
        var tail = bitString.length % 6;
        var bitStringTemp1 = bitString.substr(0, bitString.length - tail);
        var bitStringTemp2 = bitString.substr(bitString.length - tail, tail);
        for (var i = 0; i < bitStringTemp1.length; i += 6) {
            var index = parseInt(bitStringTemp1.substr(i, 6), 2);
            result += code[index];
        }
        bitStringTemp2 += new Array(7 - tail).join("0");
        if (tail) {
            result += code[parseInt(bitStringTemp2, 2)];
            result += new Array((6 - tail) / 2 + 1).join("=");
        }
        return result;
    }
 
    /**
     * @author laixiangran@163.com
     * @description 將base64編碼轉換為二進位序列
     * @param  {String}
     * @return {String}
     */
    function base64ToBin(str) {
        var bitString = "";
        var tail = 0;
        for (var i = 0; i < str.length; i++) {
            if (str[i] != "=") {
                var decode = code.indexOf(str[i]).toString(2);
                bitString += (new Array(7 - decode.length)).join("0") + decode;
            } else {
                tail++;
            }
        }
        return bitString.substr(0, bitString.length - tail * 2);
    }
 
    /**
     * @author laixiangran@163.com
     * @description 將字元轉換為二進位序列
     * @param  {String} str
     * @return {String}    
     */
    function stringToBin(str) {
        var result = "";
        for (var i = 0; i < str.length; i++) {
            var charCode = str.charCodeAt(i).toString(2);
            result += (new Array(9 - charCode.length).join("0") + charCode);
        }
        return result;
    }

    /**
     * @author laixiangran@163.com
     * @description 將二進位序列轉換為字元串
     * @param {String} Bin
     */
    function BinToStr(Bin) {
        var result = "";
        for (var i = 0; i < Bin.length; i += 8) {
            result += String.fromCharCode(parseInt(Bin.substr(i, 8), 2));
        }
        return result;
    }
    exports.base64 = function(str) {
        return binToBase64(stringToBin(str));
    }
    exports.decodeBase64 = function(str) {
        return BinToStr(base64ToBin(str));
    }
})

將圖片數據進行Base64編碼

將圖片數據轉換為Base64,首先要獲取到圖片的二進位數據。圖片的二進位數據可以通過canvas介面得到。具體實現為:

function getCanvas(w, h) {
    var c = document.createElement('canvas');
    c.width = w;
    c.height = h;
    return c;
}
 
function getPixels(img) {
    var c = getCanvas(img.width, img.height);
    var ctx = c.getContext('2d');
    ctx.drawImage(img, 0, 0);
    return ctx.getImageData(0, 0, c.width, c.height);
}

取到圖片的二進位數據後,接下來就要進行編碼了。因為圖片不僅包含像素信息,還包含長度,寬度信息。所以在編碼像素信息的同時也應將寬度和高度信息按某一約定進行編碼,我是這樣處理的:

  • 將圖片的像素數值數據轉換為二進位序列;
  • 將寬度和高度信息組合成字元串 $$width,height$$,轉換為二進位序列;
  • 將圖片像素信息的二進位序列和圖片寬高度的二進位序列組合起來,然後再進行Base64的編碼

具體實現為:

function img2Base64(img) {
    var imgData = getPixels(img).data;
    var imgWidth = getPixels(img).width;
    var imgHeight = getPixels(img).height;
    var bin = "";
    for (var i = 0; i < imgData.length; i++) {
        bin += base.numToString(imgData[i]);
    }
    bin = bin + base.stringToBin("$$" + imgWidth + "," + imgHeight + "$$");
    return base.binToBase64(bin);
}

將圖片Base64數據進行解碼

解碼是編碼的逆過程。過程大致為:

  • 將圖片的Base64信息進行解碼,得到包含圖片像素信息和寬高度信息的二進位序列;
  • 然後將這個二進位序列解碼成字元串,獲取高度和寬度信息;
  • 去除二進位序列中的高度和寬度信息,得到像素信息;
  • 根據像素信息生成像素矩陣;
  • 根據像素矩陣、寬度和高度創建圖片對象ImageData;
  • 利用putImageData將圖像繪製出來。

具體的代碼實現為:

function paint(imgData) {
        var canvas = document.getElementById("myCanvas");
        var ctx = canvas.getContext("2d");
        ctx.fillRect(0, 0, imgData.width, imgData.height);
        ctx.putImageData(imgData, 0, 0);
    }
 
function base642img(data) {
    var str = base.BinToStr(base.base64ToBin(data));
    var imgWidth = str.match(/\$\$(\d+),(\d+)\$\$$/, "")[1];
    var imgHeight = str.match(/\$\$(\d+),(\d+)\$\$$/, "")[2]
    var imgData = base.base64ToBin(data).replace(base.stringToBin("$$" + imgWidth + "," + imgHeight + "$$"), "");
 
    var ImageDataArray = new Uint8ClampedArray(imgWidth * imgHeight * 4);
    for (var i = 0; i < ImageDataArray.length; i++) {
        ImageDataArray[i] = parseInt(imgData.substr(i * 8, 8), 2);
    }
    return new ImageData(ImageDataArray, imgWidth, imgHeight);
 
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近利用閑暇時間,又重新研讀了一下Storm。認真對比了一下Hadoop,前者更擅長的是,實時流式數據處理,後者更擅長的是基於HDFS,通過MapReduce方式的離線數據分析計算。對於Hadoop,本身不擅長實時的數據分析處理。兩者的共同點都是分散式的架構,而且,都類似有主/從關係的概念。本文中我 ...
  • 抽象工廠模式在工廠方法模式的基礎上進行了改進,它提供了一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。 使用抽象工廠模式實現資料庫切換例子如下: 首先定義兩個對象的介面和它的多個具體的實現 然後定義抽象工廠介面,和具體的工廠,具體的工廠負責創建一系列相關的對象 客戶端使用不同的工廠實 ...
  • 話不多說,這個坑就是:瀏覽器緩存。前段時間在一個平臺上線前的一個晚上,在做最後的業務檢查時發現進入游戲頁面時一個白屏bug,看了以後是js控制的頁面高度變為0所以沒顯示正常。。。嚇得我趕緊改了一番,按照流程在上線前是要走QA的,然而這時候測試妹紙已經累的不行先回去了(這幾天累的有點病)。於是沒回去的 ...
  • 添加這種樣式的電子錶 1.打開後臺設置 博客側邊欄公告(支持HTML代碼)添加以下代碼 如果你是用的是新模板當加入本代碼時會時模板錯亂,但是不用慌張只要重新應用一下模板就ok啦! 如果覺得對您有幫助歡迎推薦!!您的推薦將是我的最大動力 ...
  • DeviceOne平臺包含2個基礎的佈局組件,do_ALayout和do_Linearlayout。所謂佈局組件就是在IDE里設計界面,可以拖拽別的組件加到這個佈局組件里作為這個佈局組件內的一個部分。 註意:do_ScrollView也算是佈局,也可以往裡面拖拽其他組件,不過它比較特殊,它有且只有一 ...
  • 學習要點:1.表格2.按鈕 主講教師:李炎恢 本節課我們主要學習一下 Bootstrap 表格和按鈕功能,通過內置的 CSS 定義,顯示各種豐富的效果。 一.表格Bootstrap 提供了一些豐富的表格樣式供開發者使用。1.基本格式//實現基本的表格樣式<table class="table">註: ...
  • AngularJS表單 AngularJS表單時輸入控制項的集合HTML控制項 一下HTML input 元素被稱為HTML 控制項: input 元素 select元素 button元素 textarea元素 HTML 表單 AngularjS表單上實例 <div ng-app="myApp" ng-c ...
  • 學習要點:1.頁面排版 主講教師:李炎恢 本節課我們主要學習一下 Bootstrap 全局 CSS 樣式中的排版樣式,包括了標題、頁面主體、對齊、列表等常規內容。 一.頁面排版Bootstrap 提供了一些常規設計好的頁面排版的樣式供開發者使用。1.頁面主體Bootstrap 將全局 font-si ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...