将字节值数组转换为 base64 编码的字符串并打破长行,Javascript(代码高尔夫)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5366727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert array of byte values to base64 encoded string and break long lines, Javascript (code golf)
提问by zwol
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:
这个 JavaScript 函数接受一个数字数组(在 0-255 范围内)并转换为 base64 编码的字符串,然后在必要时断开长行:
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.
你能用更少的代码做同样的事情吗?你能不能让它运行得更快?可移植性没有问题,如果需要,可以使用全新的语言功能,但必须使用 JavaScript。
回答by Anomie
I have another entry:
我有另一个条目:
function encode(data)
{
var str = String.fromCharCode.apply(null,data);
return btoa(str).replace(/.{76}(?=.)/g,'$&\n');
}
Minified, 88 characters:
缩小,88 个字符:
function e(d){return btoa(String.fromCharCode.apply(d,d)).replace(/.{76}(?=.)/g,'$&\n')}
Or if you want trailing newlines, 85 characters:
或者,如果您想要尾随换行符,85 个字符:
function e(d){return btoa(String.fromCharCode.apply(d,d)).replace(/.{1,76}/g,'$&\n')}
回答by Anomie
Works in Firefox 3.6.13:
适用于 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');
}
回答by Gabe
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:
我手边没有 Firefox,所以无法试用,但从一般的字符串处理角度来看,您似乎还有一些改进的空间。您正在做的是,对于每个字节,创建一个比前一个长一个字符的新字符串。这是一个 O(N^2) 操作。有几种方法可以减少 N,以便您的算法在接近线性的时间内运行:
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.
建立长度为 57 的字符串(这将产生一个 76 字符的 Base64 结果),然后对其执行 a
btoa
并将结果字符串添加到您的输出就像#1 一样,只构建一个行数组并调用
join
它来创建最终的输出字符串。使用
map
创建的单字符数组,然后调用join
就可以了。
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):
这是最后一个,缩小(116 个字符):
function e(b){return btoa(b.map(function(d){return
String.fromCharCode(d)}).join("")).replace(/.{76}(?=.)/g,'$&\n')}