简体   繁体   English

将字节值数组转换为base64编码的字符串并打破长行,Javascript(代码高尔夫)

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

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。

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')}

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

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. 我没有Firefox的方便,所以我无法尝试,但从一般的字符串处理角度看,你看起来有一些改进的空间。 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. 这是O(N ^ 2)操作。 There are a few ways to cut down N so that your algorithm runs in near-linear time: 有几种方法可以减少N,以便您的算法在接近线性的时间内运行:

  1. 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 构建长度为57的字符串(这将产生76-char Base64结果),然后对其执行btoa并将结果字符串添加到输出

  2. Just like #1, only build an array of lines and call join on it to create the final output string. 就像#1一样,只构建一个行数组并在其上调用join来创建最终的输出字符串。

  3. Use map to create an array of 1-character strings, then call join on it. 使用map创建一个包含1个字符的字符串数组,然后在其上调用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')}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM