在客户端Javascript中进行Base64编码和解码

时间:2010-05-12 15:25:01

标签: javascript base64

JavaScript中是否有可用于使用base64编码对字符串进行编码和解码的方法?

16 个答案:

答案 0 :(得分:176)

某些浏览器(如Firefox,Chrome,Safari,Opera和IE10 +)可以本机处理Base64。看一下这个Stackoverflow question。它正在使用btoa() and atob() functions

对于服务器端JavaScript,有一个btoa package for Node.JS

如果您要使用跨浏览器解决方案,则可以使用CryptoJS等现有库或类似代码:

http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

使用后者,您需要彻底测试该功能以实现跨浏览器兼容性。错误has already been reported

答案 1 :(得分:62)

在基于Gecko / WebKit的浏览器(Firefox,Chrome和Safari)和Opera中,您可以使用btoa()atob()

原始答案:How can you encode a string to Base64 in JavaScript?

答案 2 :(得分:47)

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!"

跨浏览器

Re-written and modularized UTF-8 and Base64 Javascript Encoding and Decoding Libraries / Modules for AMD, CommonJS, Nodejs and Browsers. Cross-browser compatible.


与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=');
}]);

但是怎么样?

如果您想了解更多关于base64如何编码的信息,特别是在JavaScript中,我会推荐这篇文章:Computer science in JavaScript: Base64 encoding

答案 3 :(得分:38)

这是一个收紧版本的狙击手的帖子。它假设格式良好的base64字符串没有回车符。这个版本消除了几个循环,添加了Yaroslav的&0xff修复,消除了尾随空值,加上一些代码高尔夫。

decodeBase64 = function(s) {
    var e={},i,b=0,c,x,l=0,a,r='',w=String.fromCharCode,L=s.length;
    var A="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    for(i=0;i<64;i++){e[A.charAt(i)]=i;}
    for(x=0;x<L;x++){
        c=e[s.charAt(x)];b=(b<<6)+c;l+=6;
        while(l>=8){((a=(b>>>(l-=8))&0xff)||(x<(L-2)))&&(r+=w(a));}
    }
    return r;
};

答案 4 :(得分:30)

短而快的Base64 JavaScript解码函数,不带故障保护:

function decode_base64 (s)
{
    var e = {}, i, k, v = [], r = '', w = String.fromCharCode;
    var n = [[65, 91], [97, 123], [48, 58], [43, 44], [47, 48]];

    for (z in n)
    {
        for (i = n[z][0]; i < n[z][1]; i++)
        {
            v.push(w(i));
        }
    }
    for (i = 0; i < 64; i++)
    {
        e[v[i]] = i;
    }

    for (i = 0; i < s.length; i+=72)
    {
        var b = 0, c, x, l = 0, o = s.substring(i, i+72);
        for (x = 0; x < o.length; x++)
        {
            c = e[o.charAt(x)];
            b = (b << 6) + c;
            l += 6;
            while (l >= 8)
            {
                r += w((b >>> (l -= 8)) % 256);
            }
         }
    }
    return r;
}

答案 5 :(得分:11)

php.js项目具有许多PHP函数的JavaScript实现。包含base64_encodebase64_decode

答案 6 :(得分:9)

function b64_to_utf8( str ) {
  return decodeURIComponent(escape(window.atob( str )));
}

 https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_.22Unicode_Problem.22

答案 7 :(得分:8)

有人说代码高尔夫吗? =)

以下是我在追赶时代的同时改善差点的尝试。提供方便。

function decode_base64(s) {
  var b=l=0, r='',
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  s.split('').forEach(function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
  });
  return r;
}

我实际上是一个异步实现,令我惊讶的是,结果是forEach而不是JQuery的$([]).each方法实现非常同步。

如果您还有这样的疯狂概念,0延迟window.setTimeout将异步运行base64解码,并在完成后执行回调函数。

function decode_base64_async(s, cb) {
  setTimeout(function () { cb(decode_base64(s)); }, 0);
}

@Toothbrush建议“索引像数组一样的字符串”,并摆脱split。这个例程似乎很奇怪,并且不确定它会有多兼容,但它确实击中了另一只小鸟,所以让它拥有它。

function decode_base64(s) {
  var b=l=0, r='',
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  [].forEach.call(s, function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
  });
  return r;
}

在尝试查找有关JavaScript字符串作为数组的更多信息时,我偶然发现了使用/./g正则表达式逐步执行字符串的专业提示。通过替换现有的字符串并消除保留返回变量的需要,这可以进一步减少代码大小。

function decode_base64(s) {
  var b=l=0,
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  return s.replace(/./g, function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    return l<8?'':String.fromCharCode((b>>>(l-=8))&0xff);
  });
}

如果您正在寻找更传统的东西,或许以下更符合您的口味。

function decode_base64(s) {
  var b=l=0, r='', s=s.split(''), i,
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  for (i in s) {
    b=(b<<6)+m.indexOf(s[i]); l+=6;
    if (l>=8) r+=String.fromCharCode((b>>>(l-=8))&0xff);
  }
  return r;
}

我没有尾随空问题因此删除后保持低于标准但是如果您愿意,可以使用trim()trimRight()轻松解决此问题你的问题。

return r.trimRight();

注意:

结果是一个ascii字节字符串,如果你需要unicode,最简单的是escape字节字符串,然后用decodeURIComponent解码,产生unicode字符串。

function decode_base64_usc(s) {      
  return decodeURIComponent(escape(decode_base64(s)));
}

由于escape被弃用,我们可以更改我们的功能以直接支持unicode而无需escapeString.fromCharCode我们可以为URI生成%转义字符串解码。

function decode_base64(s) {
  var b=l=0,
  m='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
  return decodeURIComponent(s.replace(/./g, function (v) {
    b=(b<<6)+m.indexOf(v); l+=6;
    return l<8?'':'%'+(0x100+((b>>>(l-=8))&0xff)).toString(16).slice(-2);
  }));
}

的nJoy!

答案 8 :(得分:6)

我在phpjs.org上尝试过Javascript例程并且运行良好。

我首先尝试了Ranhiru Cooray所选答案中提出的惯例 - http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

我发现他们在所有情况下都不起作用。我编写了一个测试用例,其中这些例程失败并将它们发布到GitHub:

https://github.com/scottcarter/base64_javascript_test_data.git

我还在ntt.cc的博客帖子上发表评论,提醒作者(等待审核 - 文章很旧,所以不确定是否会发布评论)。

答案 9 :(得分:2)

对于它的价值,我从其他答案中得到启发,并编写了一个小的实用程序,该实用程序调用可从Node.js或浏览器通用的平台特定的API:

/**
 * Encode a string of text as base64
 *
 * @param data The string of text.
 * @returns The base64 encoded string.
 */
function encodeBase64(data: string) {
    if (typeof btoa === "function") {
        return btoa(data);
    } else if (typeof Buffer === "function") {
        return Buffer.from(data, "utf-8").toString("base64");
    } else {
        throw new Error("Failed to determine the platform specific encoder");
    }
}

/**
 * Decode a string of base64 as text
 *
 * @param data The string of base64 encoded text
 * @returns The decoded text.
 */
function decodeBase64(data: string) {
    if (typeof atob === "function") {
        return atob(data);
    } else if (typeof Buffer === "function") {
        return Buffer.from(data, "base64").toString("utf-8");
    } else {
        throw new Error("Failed to determine the platform specific decoder");
    }
}

答案 10 :(得分:1)

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

答案 11 :(得分:1)

在Node.js中,我们可以用简单的方式完成

var base64 = 'SGVsbG8gV29ybGQ='
var base64_decode = new Buffer(base64, 'base64').toString('ascii');

console.log(base64_decode); // "Hello World"

答案 12 :(得分:1)

现代浏览器具有内置的javascript函数,用于Base64编码btoa()和解码atob()。有关旧版浏览器中支持的更多信息:https://caniuse.com/?search=atob

但是,请注意atobbtoa函数仅适用于ASCII字符集。 如果您需要Base64函数用于UTF-8字符集,则可以执行以下操作:

function base64_encode(s) {      
    return btoa(unescape(encodeURIComponent(s)));
}
function base64_decode(s) {      
    return decodeURIComponent(escape(atob(s)));
}

答案 13 :(得分:1)

前端:上面的解决方案很好,但后端很快......

NodeJS - 没有弃用

使用Buffer.from

> inBase64 = Buffer.from('plain').toString('base64')
'cGxhaW4='

> // DEPRECATED //
> new Buffer(inBase64, 'base64').toString()
'plain'
> (node:1188987) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
(Use `node --trace-deprecation ...` to show where the warning was created)

// Works //
> Buffer.from(inBase64, 'base64').toString()
'plain'

答案 14 :(得分:0)

对于没有atob方法的JavaScript框架,如果您不想导入外部库,这是一个简短的函数。

它将得到一个包含Base64编码值的字符串,并返回一个解码的字节数组(其中字节数组表示为数字数组,其中每个数字都是0到255之间的整数)。

function fromBase64String(str) {
    var alpha = 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    var value = [];
    var index = 0;
    var destIndex  = 0;
    var padding = false;
    while (true) {

        var first  = getNextChr(str, index, padding, alpha);
        var second = getNextChr(str, first .nextIndex, first .padding, alpha);
        var third  = getNextChr(str, second.nextIndex, second.padding, alpha);
        var fourth = getNextChr(str, third .nextIndex, third .padding, alpha);

        index = fourth.nextIndex;
        padding = fourth.padding;

        // ffffffss sssstttt ttffffff
        var base64_first  = first.code  == null ? 0 : first.code;
        var base64_second = second.code == null ? 0 : second.code;
        var base64_third  = third.code  == null ? 0 : third.code;
        var base64_fourth = fourth.code == null ? 0 : fourth.code;

        var a = (( base64_first << 2) & 0xFC ) | ((base64_second>>4) & 0x03);
        var b = (( base64_second<< 4) & 0xF0 ) | ((base64_third >>2) & 0x0F);
        var c = (( base64_third << 6) & 0xC0 ) | ((base64_fourth>>0) & 0x3F);

        value [destIndex++] = a;
        if (!third.padding) {
            value [destIndex++] = b;
        } else {
            break;
        }
        if (!fourth.padding) {
            value [destIndex++] = c;
        } else {
            break;
        }
        if (index >= str.length) {
            break;
        }
    }
    return value;
}

function getNextChr(str, index, equalSignReceived, alpha) {
    var chr = null;
    var code = 0;
    var padding = equalSignReceived;
    while (index < str.length) {
        chr = str.charAt(index);
        if (chr == " " || chr == "\r" || chr == "\n" || chr == "\t") {
            index++;
            continue;
        }
        if (chr == "=") {
            padding = true;
        } else {
            if (equalSignReceived) {
                throw new Error("Invalid Base64 Endcoding character \"" 
                    + chr + "\" with code " + str.charCodeAt(index) 
                    + " on position " + index 
                    + " received afer an equal sign (=) padding "
                    + "character has already been received. "
                    + "The equal sign padding character is the only "
                    + "possible padding character at the end.");
            }
            code = alpha.indexOf(chr);
            if (code == -1) {
                throw new Error("Invalid Base64 Encoding character \"" 
                    + chr + "\" with code " + str.charCodeAt(index) 
                    + " on position " + index + ".");
            }
        }
        break;
    }
    return { character: chr, code: code, padding: padding, nextIndex: ++index};
}

使用的资源:RFC-4648 Section 4

答案 15 :(得分:0)

Base64 Win-1251 解码,用于acsi 或 iso-8859-1 以外的编码。

事实证明,我在这里看到的所有脚本都将 Cyrillic Base64 转换为 iso-8859-1 编码。奇怪的是没有人注意到这一点。

因此,要恢复西里尔字母,只需将文本从 iso-8859-1 额外转码到 windows-1251。

我认为对于其他语言,它会是一样的。只需将 Cyrilic windows-1251 更改为您的。

...感谢Der Hochstapler 的代码,我从他的评论中提取...过度评论,这有点不寻常。

JScript 代码(仅适用于 Windows 桌面)(ActiveXObject) - 1251 文件编码

decode_base64=function(f){var g={},b=65,d=0,a,c=0,h,e="",k=String.fromCharCode,l=f.length;for(a="";91>b;)a+=k(b++);a+=a.toLowerCase()+"0123456789+/";for(b=0;64>b;b++)g[a.charAt(b)]=b;for(a=0;a<l;a++)for(b=g[f.charAt(a)],d=(d<<6)+b,c+=6;8<=c;)((h=d>>>(c-=8)&255)||a<l-2)&&(e+=k(h));return e};
sDOS2Win = function(sText, bInsideOut) {
    var aCharsets = ["iso-8859-1", "windows-1251"];
    sText += "";
    bInsideOut = bInsideOut ? 1 : 0;
    with (new ActiveXObject("ADODB.Stream")) { //http://www.w3schools.com/ado/ado_ref_stream.asp
        type = 2; //Binary 1, Text 2 (default) 
        mode = 3; //Permissions have not been set 0,  Read-only 1,  Write-only 2,  Read-write 3,  
        //Prevent other read 4,  Prevent other write 8,  Prevent other open 12,  Allow others all 16
        charset = aCharsets[bInsideOut]; 
        open();
        writeText(sText);
        position = 0;
        charset = aCharsets[1 - bInsideOut];
        return readText();
    }
}
var base64='0PPx8ero5SDh8+ru4uroIQ=='
text = sDOS2Win(decode_base64(base64), false );
WScript.Echo(text)
var x=WScript.StdIn.ReadLine();