首页 文章

如何在JavaScript中将字符串编码为Base64?

提问于
浏览
649

我有一个PHP脚本,可以将PNG图像编码为Base64字符串 .

我想用JavaScript做同样的事情 . 我知道如何打开文件,但我不知道如何进行编码 . 我不习惯使用二进制数据 .

22 回答

  • 10

    您可以使用btoa()atob()转换为base64编码和从base64编码转换 .

    关于这些功能接受/返回的评论似乎有些混淆,所以...

    • btoa() 接受一个“字符串”,其中每个字符代表一个8位字节 - 如果你传递的字符串包含无法用8位表示的字符,it will probably break . 如果您实际将字符串视为字节数组,这不是问题,但如果您尝试执行其他操作,则必须先对其进行编码 .

    • atob() 返回一个“字符串”,其中每个字符代表一个8位字节 - 也就是说,它的值将介于 00xff 之间 . 这并不意味着它是ASCII - 大概是你完全使用这个函数,你希望使用二进制数据而不是文本 .

    另见:

  • 5

    我需要将UTF-8字符串编码为我的项目的base64 . 这里的大多数答案在转换为UTF-8时似乎没有正确处理UTF-16代理对,因此,为了完成起见,我将发布我的解决方案:

    function strToUTF8Base64(str) {
    
        function decodeSurrogatePair(hi, lo) {
            var resultChar = 0x010000;
            resultChar += lo - 0xDC00;
            resultChar += (hi - 0xD800) << 10;
            return resultChar;
        }
    
        var bytes = [0, 0, 0];
        var byteIndex = 0;
        var result = [];
    
        function output(s) {
            result.push(s);
        }
    
        function emitBase64() {
    
            var digits =
                    'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
                    'abcdefghijklmnopqrstuvwxyz' +
                    '0123456789+/';
    
            function toDigit(value) {
                return digits[value];
            }
    
            // --Byte 0--    --Byte 1--    --Byte 2--
            // 1111  1122    2222  3333    3344  4444
    
            var d1 = toDigit(bytes[0] >> 2);
            var d2 = toDigit(
                ((bytes[0] & 0x03) << 4) |
                (bytes[1] >> 4));
            var d3 = toDigit(
                ((bytes[1] & 0x0F) << 2) |
                (bytes[2] >> 6));
            var d4 = toDigit(
                bytes[2] & 0x3F);
    
            if (byteIndex === 1) {
                output(d1 + d2 + '==');
            }
            else if (byteIndex === 2) {
                output(d1 + d2 + d3 + '=');
            }
            else {
                output(d1 + d2 + d3 + d4);
            }
        }
    
        function emit(chr) {
            bytes[byteIndex++] = chr;
            if (byteIndex == 3) {
                emitBase64();
                bytes[0] = 0;
                bytes[1] = 0;
                bytes[2] = 0;
                byteIndex = 0;
            }
        }
    
        function emitLast() {
            if (byteIndex > 0) {
                emitBase64();
            }
        }
    
        // Converts the string to UTF8:
    
        var i, chr;
        var hi, lo;
        for (i = 0; i < str.length; i++) {
            chr = str.charCodeAt(i);
    
            // Test and decode surrogate pairs in the string
            if (chr >= 0xD800 && chr <= 0xDBFF) {
                hi = chr;
                lo = str.charCodeAt(i + 1);
                if (lo >= 0xDC00 && lo <= 0xDFFF) {
                    chr = decodeSurrogatePair(hi, lo);
                    i++;
                }
            }
    
            // Encode the character as UTF-8.
            if (chr < 0x80) {
                emit(chr);
            }
            else if (chr < 0x0800) {
                emit((chr >> 6) | 0xC0);
                emit(((chr >> 0) & 0x3F) | 0x80);
            }
            else if (chr < 0x10000) {
                emit((chr >> 12) | 0xE0);
                emit(((chr >>  6) & 0x3F) | 0x80);
                emit(((chr >>  0) & 0x3F) | 0x80);
            }
            else if (chr < 0x110000) {
                emit((chr >> 18) | 0xF0);
                emit(((chr >> 12) & 0x3F) | 0x80);
                emit(((chr >>  6) & 0x3F) | 0x80);
                emit(((chr >>  0) & 0x3F) | 0x80);
            }
        }
    
        emitLast();
    
        return result.join('');
    }
    

    请注意,代码未经过全面测试 . 我测试了一些输入,包括 strToUTF8Base64('衠衢蠩蠨') 之类的东西,并与在线编码工具(https://www.base64encode.org/)的输出进行了比较 .

  • 15

    你可以使用 window.btoawindow.atob ......

    const encoded = window.btoa('Alireza Dezfoolian'); // encode a string
    const decoded = window.atob(encoded); // decode the string
    

    可能使用 MDN 的方式可以做到最好...同时接受unicode ......使用这两个简单的函数:

    // ucs-2 string to base64 encoded ascii
    function utoa(str) {
        return window.btoa(unescape(encodeURIComponent(str)));
    }
    // base64 encoded ascii to ucs-2 string
    function atou(str) {
        return decodeURIComponent(escape(window.atob(str)));
    }
    // Usage:
    utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
    atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
    
    utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
    atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
    
  • 20

    我已经手工重写了这些编码和解码方法,除了十六进制之外的模块化格式,用于跨平台/浏览器兼容性以及真正的私有范围,并且如果由于速度而存在则使用 btoaatob 而不是利用自己的编码:

    https://gist.github.com/Nijikokun/5192472

    用法:

    base64.encode(/* String */);
    base64.decode(/* String */);
    
    utf8.encode(/* String */);
    utf8.decode(/* String */);
    
  • 9

    如果你需要编码HTML图像对象,你可以编写简单的函数,如:

    function getBase64Image(img) {  
      var canvas = document.createElement("canvas");  
      canvas.width = img.width;  
      canvas.height = img.height;  
      var ctx = canvas.getContext("2d");  
      ctx.drawImage(img, 0, 0);  
      var dataURL = canvas.toDataURL("image/png");  
      // escape data:image prefix
      return dataURL.replace(/^data:image\/(png|jpg);base64,/, "");  
      // or just return dataURL
      // return dataURL
    }
    

    要通过id获取base64的图像:

    function getBase64ImageById(id){  
      return getBase64Image(document.getElementById(id));  
    }
    

    更多here

  • 3

    对于我的项目,我仍然需要支持IE7并使用大输入进行编码 .

    根据Joe Dyndale提出的代码和Marius的评论建议,通过使用数组而不是字符串构造结果,可以提高IE7的性能 .

    以下是编码的示例:

    var encode = function (input) {
        var output = [], chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
    
        input = _utf8_encode(input);
    
        while (i < input.length) {
    
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
    
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
    
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
    
            output.push(_keyStr.charAt(enc1));
            output.push(_keyStr.charAt(enc2));
            output.push(_keyStr.charAt(enc3));
            output.push(_keyStr.charAt(enc4));
    
        }
    
        return output.join("");
    };
    
  • 90

    好吧,如果您使用的是dojo,它为我们提供了直接编码或解码为base64的方法 .

    试试这个:-

    使用dojox.encoding.base64编码字节数组:

    var str = dojox.encoding.base64.encode(myByteArray);
    

    要解码base64编码的字符串:

    var bytes = dojox.encoding.base64.decode(str);
    
  • 4

    从接受的答案下面的评论(由SET和Stefan Steiger),这里是如何在不需要库的情况下将字符串编码/解码到base64的快速摘要 .

    str = "The quick brown fox jumps over the lazy dog";
    b64 = btoa(unescape(encodeURIComponent(str)));
    str = decodeURIComponent(escape(window.atob(b64)));
    

    演示

    (使用jQuery库,但不用于编码/解码)

    str = "The quick brown fox jumps over the lazy dog";
    
    $('input').val(str);
    
    $('#btnConv').click(function(){
      var txt = $('input').val();
      var b64 = btoa(unescape(encodeURIComponent(txt)));
      $('input').val(b64);
      $('#btnDeConv').show();
    });
    $('#btnDeConv').click(function(){
      var b64 = $('input').val();
      var txt = decodeURIComponent(escape(window.atob(b64)));
      $('input').val(txt);
    });
    
    #btnDeConv{display:none;}
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <input type="text" />
    <button id="btnConv">Convert</button>
    <button id="btnDeConv">DeConvert</button>
    
  • 4

    _utf8_decode 的两个实现中都存在一些错误 . 由于 var 语句的使用中断, c1c2 被指定为全局变量,并且 c3 未被初始化或声明 .

    它可以工作,但是这些变量将覆盖此函数之外具有相同名称的任何现有变量 .

    这是一个不会这样做的版本:

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = 0, c1 = 0, c2 = 0;
    
        while ( i < utftext.length ) {
    
            c = utftext.charCodeAt(i);
    
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c1 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                i += 2;
            }
            else {
                c1 = utftext.charCodeAt(i+1);
                c2 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                i += 3;
            }
    
        }
        return string;
    }
    
  • 25

    使用缩小的polyfill为 window.atob window.btoa 做贡献,我目前正在使用 .

    (function(){function t(t){this.message=t}var e="undefined"!=typeof exports?exports:this,r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";t.prototype=Error(),t.prototype.name="InvalidCharacterError",e.btoa||(e.btoa=function(e){for(var o,n,a=0,i=r,c="";e.charAt(0|a)||(i="=",a%1);c+=i.charAt(63&o>>8-8*(a%1))){if(n=e.charCodeAt(a+=.75),n>255)throw new t("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");o=o<<8|n}return c}),e.atob||(e.atob=function(e){if(e=e.replace(/=+$/,""),1==e.length%4)throw new t("'atob' failed: The string to be decoded is not correctly encoded.");for(var o,n,a=0,i=0,c="";n=e.charAt(i++);~n&&(o=a%4?64*o+n:n,a++%4)?c+=String.fromCharCode(255&o>>(6&-2*a)):0)n=r.indexOf(n);return c})})();
    
  • 87

    请注意,这不适用于原始Unicode字符串!请参见Unicode部分here .

    编码语法

    var encodedData = window.btoa(stringToEncode);

    解码语法

    var decodedData = window.atob(encodedData);

  • 4

    要使Base64编码的String URL友好,您可以在JavaScript中执行以下操作:

    // if this is your Base64 encoded string
    var str = 'VGhpcyBpcyBhbiBhd2Vzb21lIHNjcmlwdA=='; 
    
    // make URL friendly:
    str = str.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
    
    // reverse to original encoding
    str = (str + '===').slice(0, str.length + (str.length % 4));
    str = str.replace(/-/g, '+').replace(/_/g, '/');
    

    另见这个小提琴:http://jsfiddle.net/magikMaker/7bjaT/

  • 5

    Internet Explorer 10

    // Define the string
    var string = 'Hello World!';
    
    // Encode the String
    var encodedString = btoa(string);
    console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
    
    // Decode the String
    var decodedString = atob(encodedString);
    console.log(decodedString); // Outputs: "Hello World!"
    

    跨浏览器

    // Create Base64 Object
    var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
    
    // Define the string
    var string = 'Hello World!';
    
    // Encode the String
    var encodedString = Base64.encode(string);
    console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"
    
    // Decode the String
    var decodedString = Base64.decode(encodedString);
    console.log(decodedString); // Outputs: "Hello World!"
    

    jsFiddle


    带有Node.js的

    以下是在Node.js中将普通文本编码为base64的方法:

    //Buffer() requires a number, array or string as the first parameter, and an optional encoding type as the second parameter. 
    // Default is utf8, possible encoding types are ascii, utf8, ucs2, base64, binary, and hex
    var b = new Buffer('JavaScript');
    // If we don't use toString(), JavaScript assumes we want to convert the object to utf8.
    // We can make it convert to other formats by passing the encoding type to toString().
    var s = b.toString('base64');
    

    以下是解码base64编码字符串的方法:

    var b = new Buffer('SmF2YVNjcmlwdA==', 'base64')
    var s = b.toString();
    

    与Dojo.js

    使用dojox.encoding.base64编码字节数组:

    var str = dojox.encoding.base64.encode(myByteArray);
    

    要解码base64编码的字符串:

    var bytes = dojox.encoding.base64.decode(str)
    

    bower安装angular-base64

    <script src="bower_components/angular-base64/angular-base64.js"></script>
    
    angular
        .module('myApp', ['base64'])
        .controller('myController', [
    
        '$base64', '$scope', 
        function($base64, $scope) {
    
            $scope.encoded = $base64.encode('a string');
            $scope.decoded = $base64.decode('YSBzdHJpbmc=');
    }]);
    
  • 0

    您可以使用 btoa (到base-64)和 atob (从base-64开始) .

    对于IE 9及更低版本,请尝试jquery-base64插件:

    $.base64.encode("this is a test");
    $.base64.decode("dGhpcyBpcyBhIHRlc3Q=");
    
  • 5

    这个问题及其答案向我指出了正确的方向 .
    特别是unicode atob和btoa不能使用"vanilla"而且这些天一切都是unicode ..

    直接来自Mozilla,有两个很好的功能用于此目的(内部使用unicode和html标签测试)

    function b64EncodeUnicode(str) {
        return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
            return String.fromCharCode('0x' + p1);
        }));
    }
    
    b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
    b64EncodeUnicode('\n'); // "Cg=="
    
    
    
    function b64DecodeUnicode(str) {
        return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        }).join(''));
    }
    
    b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
    b64DecodeUnicode('Cg=='); // "\n"
    

    与使用自定义javascript函数的原始base64解码相比,这些函数将执行闪电般快速,因为btoa和atob在外部执行翻译 .

    如果你可以忽略旧的IE和旧的手机(如iphone 3?),这应该是一个很好的解决方案 .

  • 682

    虽然需要更多工作,但如果您需要高性能本机解决方案,则可以使用一些HTML5功能 .

    如果您可以将数据导入Blob,那么您可以使用FileReader.readAsDataURL()函数获取 data:// URL并切断其前面以获取base64数据 .

    您可能需要进行进一步处理,然后对数据进行urldecode,因为我不确定 + 字符是否转义为 + ,但这应该是非常简单的 .

  • 6

    我宁愿使用CryptoJS中的bas64编码/解码方法,这是使用最佳实践和模式在JavaScript中实现的标准和安全加密算法的最流行的库 .

  • 13

    我答案,但我想回馈一些我为自己的项目做出的改变,以防任何人发现它有用 . 基本上我一直抱怨,并且我在评论中将标记为私有的方法实际上设为私有 . 我还在自己的项目中添加了两个我需要的方法,即 decodeToHexencodeFromHex .

    代码:

    var Base64 = (function() {
        "use strict";
    
        var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    
        var _utf8_encode = function (string) {
    
            var utftext = "", c, n;
    
            string = string.replace(/\r\n/g,"\n");
    
            for (n = 0; n < string.length; n++) {
    
                c = string.charCodeAt(n);
    
                if (c < 128) {
    
                    utftext += String.fromCharCode(c);
    
                } else if((c > 127) && (c < 2048)) {
    
                    utftext += String.fromCharCode((c >> 6) | 192);
                    utftext += String.fromCharCode((c & 63) | 128);
    
                } else {
    
                    utftext += String.fromCharCode((c >> 12) | 224);
                    utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                    utftext += String.fromCharCode((c & 63) | 128);
    
                }
    
            }
    
            return utftext;
        };
    
        var _utf8_decode = function (utftext) {
            var string = "", i = 0, c = 0, c1 = 0, c2 = 0;
    
            while ( i < utftext.length ) {
    
                c = utftext.charCodeAt(i);
    
                if (c < 128) {
    
                    string += String.fromCharCode(c);
                    i++;
    
                } else if((c > 191) && (c < 224)) {
    
                    c1 = utftext.charCodeAt(i+1);
                    string += String.fromCharCode(((c & 31) << 6) | (c1 & 63));
                    i += 2;
    
                } else {
    
                    c1 = utftext.charCodeAt(i+1);
                    c2 = utftext.charCodeAt(i+2);
                    string += String.fromCharCode(((c & 15) << 12) | ((c1 & 63) << 6) | (c2 & 63));
                    i += 3;
    
                }
    
            }
    
            return string;
        };
    
        var _hexEncode = function(input) {
            var output = '', i;
    
            for(i = 0; i < input.length; i++) {
                output += input.charCodeAt(i).toString(16);
            }
    
            return output;
        };
    
        var _hexDecode = function(input) {
            var output = '', i;
    
            if(input.length % 2 > 0) {
                input = '0' + input;
            }
    
            for(i = 0; i < input.length; i = i + 2) {
                output += String.fromCharCode(parseInt(input.charAt(i) + input.charAt(i + 1), 16));
            }
    
            return output;
        };
    
        var encode = function (input) {
            var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
    
            input = _utf8_encode(input);
    
            while (i < input.length) {
    
                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);
    
                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;
    
                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }
    
                output += _keyStr.charAt(enc1);
                output += _keyStr.charAt(enc2);
                output += _keyStr.charAt(enc3);
                output += _keyStr.charAt(enc4);
    
            }
    
            return output;
        };
    
        var decode = function (input) {
            var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
    
            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    
            while (i < input.length) {
    
                enc1 = _keyStr.indexOf(input.charAt(i++));
                enc2 = _keyStr.indexOf(input.charAt(i++));
                enc3 = _keyStr.indexOf(input.charAt(i++));
                enc4 = _keyStr.indexOf(input.charAt(i++));
    
                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;
    
                output += String.fromCharCode(chr1);
    
                if (enc3 !== 64) {
                    output += String.fromCharCode(chr2);
                }
                if (enc4 !== 64) {
                    output += String.fromCharCode(chr3);
                }
    
            }
    
            return _utf8_decode(output);
        };
    
        var decodeToHex = function(input) {
            return _hexEncode(decode(input));
        };
    
        var encodeFromHex = function(input) {
            return encode(_hexDecode(input));
        };
    
        return {
            'encode': encode,
            'decode': decode,
            'decodeToHex': decodeToHex,
            'encodeFromHex': encodeFromHex
        };
    }());
    
  • 275

    From here

    /**
    *
    *  Base64 encode / decode
    *  http://www.webtoolkit.info/
    *
    **/
    var Base64 = {
    
    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    
    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;
    
        input = Base64._utf8_encode(input);
    
        while (i < input.length) {
    
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
    
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
    
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
    
            output = output +
            this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
            this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
    
        }
    
        return output;
    },
    
    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
    
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    
        while (i < input.length) {
    
            enc1 = this._keyStr.indexOf(input.charAt(i++));
            enc2 = this._keyStr.indexOf(input.charAt(i++));
            enc3 = this._keyStr.indexOf(input.charAt(i++));
            enc4 = this._keyStr.indexOf(input.charAt(i++));
    
            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;
    
            output = output + String.fromCharCode(chr1);
    
            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }
    
        }
    
        output = Base64._utf8_decode(output);
    
        return output;
    
    },
    
    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";
    
        for (var n = 0; n < string.length; n++) {
    
            var c = string.charCodeAt(n);
    
            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
    
        }
    
        return utftext;
    },
    
    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;
    
        while ( i < utftext.length ) {
    
            c = utftext.charCodeAt(i);
    
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
    
        }
    
        return string;
    }
    
    }
    

    此外,搜索"javascript base64 encoding"转了很多其他选项,上面是第一个 .

  • 92

    Sunny的代码很棒,除非它在IE7中因为引用“this”而中断 . 通过用“Base64”替换这些引用来修复:

    var Base64 = {
    // private property
    _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    
    // public method for encoding
    encode : function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;
    
        input = Base64._utf8_encode(input);
    
        while (i < input.length) {
    
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
    
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
    
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
    
            output = output +
            Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
            Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
    
        }
    
        return output;
    },
    
    // public method for decoding
    decode : function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
    
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    
        while (i < input.length) {
    
            enc1 = Base64._keyStr.indexOf(input.charAt(i++));
            enc2 = Base64._keyStr.indexOf(input.charAt(i++));
            enc3 = Base64._keyStr.indexOf(input.charAt(i++));
            enc4 = Base64._keyStr.indexOf(input.charAt(i++));
    
            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;
    
            output = output + String.fromCharCode(chr1);
    
            if (enc3 != 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 != 64) {
                output = output + String.fromCharCode(chr3);
            }
    
        }
    
        output = Base64._utf8_decode(output);
    
        return output;
    
    },
    
    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";
    
        for (var n = 0; n < string.length; n++) {
    
            var c = string.charCodeAt(n);
    
            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
    
        }
    
        return utftext;
    },
    
    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;
    
        while ( i < utftext.length ) {
    
            c = utftext.charCodeAt(i);
    
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
    
        }
        return string;
    }
    }
    
  • 9

    这是@ user850789的AngularJS Factory版本之一:

    'use strict';
    
    var ProjectNameBase64Factory = angular.module('project_name.factories.base64', []);
    
    ProjectNameBase64Factory.factory('Base64', function () {
        var Base64 = {
            // private property
            _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
    
            // public method for encoding
            encode: function (input) {
                var output = "";
                var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
                var i = 0;
    
                input = Base64._utf8_encode(input);
    
                while (i < input.length) {
    
                    chr1 = input.charCodeAt(i++);
                    chr2 = input.charCodeAt(i++);
                    chr3 = input.charCodeAt(i++);
    
                    enc1 = chr1 >> 2;
                    enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                    enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                    enc4 = chr3 & 63;
    
                    if (isNaN(chr2)) {
                        enc3 = enc4 = 64;
                    } else if (isNaN(chr3)) {
                        enc4 = 64;
                    }
    
                    output = output +
                             Base64._keyStr.charAt(enc1) + Base64._keyStr.charAt(enc2) +
                             Base64._keyStr.charAt(enc3) + Base64._keyStr.charAt(enc4);
    
                }
    
                return output;
            },
    
            // public method for decoding
            decode: function (input) {
                var output = "";
                var chr1, chr2, chr3;
                var enc1, enc2, enc3, enc4;
                var i = 0;
    
                input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
    
                while (i < input.length) {
    
                    enc1 = Base64._keyStr.indexOf(input.charAt(i++));
                    enc2 = Base64._keyStr.indexOf(input.charAt(i++));
                    enc3 = Base64._keyStr.indexOf(input.charAt(i++));
                    enc4 = Base64._keyStr.indexOf(input.charAt(i++));
    
                    chr1 = (enc1 << 2) | (enc2 >> 4);
                    chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                    chr3 = ((enc3 & 3) << 6) | enc4;
    
                    output = output + String.fromCharCode(chr1);
    
                    if (enc3 != 64) {
                        output = output + String.fromCharCode(chr2);
                    }
                    if (enc4 != 64) {
                        output = output + String.fromCharCode(chr3);
                    }
    
                }
    
                output = Base64._utf8_decode(output);
    
                return output;
    
            },
    
            // private method for UTF-8 encoding
            _utf8_encode: function (string) {
                string = string.replace(/\r\n/g, "\n");
                var utftext = "";
    
                for (var n = 0; n < string.length; n++) {
    
                    var c = string.charCodeAt(n);
    
                    if (c < 128) {
                        utftext += String.fromCharCode(c);
                    }
                    else if ((c > 127) && (c < 2048)) {
                        utftext += String.fromCharCode((c >> 6) | 192);
                        utftext += String.fromCharCode((c & 63) | 128);
                    }
                    else {
                        utftext += String.fromCharCode((c >> 12) | 224);
                        utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                        utftext += String.fromCharCode((c & 63) | 128);
                    }
    
                }
    
                return utftext;
            },
    
            // private method for UTF-8 decoding
            _utf8_decode: function (utftext) {
                var string = "";
                var i = 0;
                var c = 0, c2 = 0, c3 = 0;
    
                while (i < utftext.length) {
    
                    c = utftext.charCodeAt(i);
    
                    if (c < 128) {
                        string += String.fromCharCode(c);
                        i++;
                    }
                    else if ((c > 191) && (c < 224)) {
                        c2 = utftext.charCodeAt(i + 1);
                        string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                        i += 2;
                    }
                    else {
                        c2 = utftext.charCodeAt(i + 1);
                        c3 = utftext.charCodeAt(i + 2);
                        string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                        i += 3;
                    }
    
                }
                return string;
            }
        };
        return Base64;
    });
    
  • 11

    对于较新的浏览器,将Uint8Array编码为字符串,并将字符串解码为Uint8Array .

    const base64 = {
        decode: s => Uint8Array.from(atob(s), c => c.charCodeAt(0)),
        encode: b => btoa(String.fromCharCode(...new Uint8Array(b)))
    };
    

    对于Node.js,您可以使用以下命令将string,Buffer或Uint8Array编码为string,并将string,Buffer或Uint8Array解码为Buffer .

    const base64 = {
        decode: s => Buffer.from(s, 'base64'),
        encode: b => Buffer.from(b).toString('base64')
    };
    

相关问题