I don't have Firefox handy, so I can't try it out, but from a general string-handling perspective it looks like you have some room to improve. What you're doing is, for every byte, creating a new string one character longer than your previous one. This is an O(N^2) operation. There are a few ways to cut down N so that your algorithm runs in near-linear time:
Build up strings to length 57 (this will yield a 76-char Base64 result), then perform a btoa
on it and add the resulting string to your output
Just like #1, only build an array of lines and call join
on it to create the final output string.
Use map
to create an array of 1-character strings, then call join
on it.
Here's some untested code for each method:
function encode(data)
{
var output = "";
var str = "";
for (var i = 0; i < data.length; i++)
{
str += String.fromCharCode(data[i]);
// the "&& i != data.length - 1" clause
// keeps the extra \n off the end of the output
// when the last line is exactly 76 characters
if (str.length == 57 && i != data.length - 1)
{
output += btoa(str) + "\n";
str = "";
}
}
return output + btoa(str);
}
function encode(data)
{
var output = [];
var str = "";
for (var i = 0; i < data.length; i++)
{
str += String.fromCharCode(data[i]);
if (str.length == 57)
{
output[output.length] = btoa(str);
str = "";
}
}
if (str != "")
output[output.length] = btoa(str);
return output.join("\n");
}
function encode(data)
{
var str = data.map(function (d) { return String.fromCharCode(d) }).join("");
return btoa(str).replace(/.{76}(?=.)/g,'$&\n');
}
And here's the last one, minified (116 chars):
function e(b){return btoa(b.map(function(d){return
String.fromCharCode(d)}).join("")).replace(/.{76}(?=.)/g,'$&\n')}