将字节值数组转换为 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 16:57:23  来源:igfitidea点击:

Convert array of byte values to base64 encoded string and break long lines, Javascript (code golf)

javascriptfirefox-addon

提问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,以便您的算法在接近线性的时间内运行:

  1. Build up strings to length 57 (this will yield a 76-char Base64 result), then perform a btoaon it and add the resulting string to your output

  2. Just like #1, only build an array of lines and call joinon it to create the final output string.

  3. Use mapto create an array of 1-character strings, then call joinon it.

  1. 建立长度为 57 的字符串(这将产生一个 76 字符的 Base64 结果),然后对其执行 abtoa并将结果字符串添加到您的输出

  2. 就像#1 一样,只构建一个行数组并调用join它来创建最终的输出字符串。

  3. 使用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')}