This JavaScript function takes an array of numbers (in the range 0-255) and converts to a base64-encoded string, then breaks long lines if necessary:
function encode(data)
{
var str = "";
for (var i = 0; i < data.length; i++)
str += String.fromCharCode(data[i]);
return btoa(str).split(/(.{75})/).join("\n").replace(/\n+/g, "\n").trim();
}
Can you do the same thing in less code? Can you do it so it runs faster? Portability no object, use brand new language features if you want, but 's gotta be in JavaScript.
This JavaScript function takes an array of numbers (in the range 0-255) and converts to a base64-encoded string, then breaks long lines if necessary:
function encode(data)
{
var str = "";
for (var i = 0; i < data.length; i++)
str += String.fromCharCode(data[i]);
return btoa(str).split(/(.{75})/).join("\n").replace(/\n+/g, "\n").trim();
}
Can you do the same thing in less code? Can you do it so it runs faster? Portability no object, use brand new language features if you want, but 's gotta be in JavaScript.
Share Improve this question edited Oct 27, 2018 at 9:31 Cœur 38.7k26 gold badges202 silver badges277 bronze badges asked Mar 20, 2011 at 4:11 zwolzwol 141k39 gold badges268 silver badges384 bronze badges 4 |3 Answers
Reset to default 14I have another entry:
function encode(data)
{
var str = String.fromCharCode.apply(null,data);
return btoa(str).replace(/.{76}(?=.)/g,'$&\n');
}
Minified, 88 characters:
function e(d){return btoa(String.fromCharCode.apply(d,d)).replace(/.{76}(?=.)/g,'$&\n')}
Or if you want trailing newlines, 85 characters:
function e(d){return btoa(String.fromCharCode.apply(d,d)).replace(/.{1,76}/g,'$&\n')}
Works in Firefox 3.6.13:
function encode(data)
{
var str = data.reduce(function(a,b){ return a+String.fromCharCode(b) },'');
return btoa(str).replace(/.{76}(?=.)/g,'$&\n');
}
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 outputJust 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 calljoin
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')}
btoa
is only supported by Gecko and WebKit browsers as far as I know. – Gabe Commented Mar 20, 2011 at 4:41