6
votes

Convertir une palette de valeurs d'octet à la chaîne codée de base64 et à la pause de lignes longues, JavaScript (code golf)

Cette fonction JavaScript prend une matrice de chiffres (dans la plage 0-255) et convertit sur une chaîne codée de base64, puis casse les lignes longues si nécessaire:

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


4 commentaires

Fonctionne plus vite dans quel (s) navigateur (s)? BTOA est uniquement pris en charge par Gecko et WebKit Naviers aussi loin que je sache.


Comme cela se produit, il s'agit d'une très petite pièce d'extension de Firefox, mais si vous avez un moyen intelligent de le faire en utilisant des JS d'un autre navigateur, je serais heureux de le voir aussi.


Ahem ... codegolf.stackexchange.com


@jessegavin: CodeGolf.se est juste pour le divertissement; C'est un problème de programmation légitime réel.


3 Réponses :


3
votes

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


4 commentaires

Avez-vous besoin de ce garniture là-bas?


@Gabe: Je l'ai mis pour éviter la chaîne retournée ayant une cheviche de fin lorsque la chaîne codée de base64 est un multiple exact de la longueur de la ligne tout en manquant autrement. Mais lorsque vous écrivez cela en réponse à vous, je pensais que "le moteur JavaScript JavaScript de Firefox supporte-t-il la largeur zéro-largeur positive?". Et ça fait! Édité.


Oh, est l'objet ici des caractères minimum? Cela peut être minifié à 116 caractères, ou 113 si vous voulez que chaque sortie ait une nouvelle ligne de fin (modifier la regex sur /. {1,76} / g ).


Minimum Les caractères ne sont pas vraiment le but - je vais courir tout ce qui est via un mineur automatique dans tous les cas - mais minimum Opérations est souhaitable. J'aime l'utilisation de Réduire Bien que j'imagine que ce n'est pas plus rapide que la boucle pour la boucle, car le gros coût ici va grandir la chaîne.



1
votes

Je n'ai pas de firefox à portée de main, je ne peux donc pas l'essayer, mais d'une perspective générale de manutention à la chaîne, on dirait que vous avez une place à améliorer. Ce que vous faites est, pour chaque octet, créant une nouvelle chaîne un personnage plus longtemps que votre précédent. C'est une opération O (n ^ 2). Il y a quelques façons de couper n afin que votre algorithme fonctionne en temps quasi linéaire:

  1. Construisement des chaînes à longueur 57 (cela donnera un résultat de 76 caractères644), puis effectuez un BTOA dessus et ajoutez la chaîne résultante à votre sortie < / li>

  2. juste comme n ° 1, ne construisez qu'une gamme de lignes et appelez joindre sur celui-ci pour créer la chaîne de sortie finale.

  3. Utilisez mappe pour créer un tableau de chaînes de 1 caractères, puis appelez joindre dessus.

    Voici un code non testé pour chaque méthode: xxx

    et voici le dernier, minifié (116 caractères): xxx


2 commentaires

Une fermeture est requise, car la carte appelle sa fonction avec 3 args (élément de tableau, index et objet de tableau) et stress.fromcharcode peut prendre plusieurs points de code comme des arguments pour renvoyer une chaîne de caractères multiples. Par coïncidence, je me suis souvenu de cela juste avant de poster et de réaliser que je pourrais profiter de ce fait.


J'aime l'idée de chunking 57 octets à la fois pour nourrir BTOA .



13
votes

J'ai une autre entrée: xxx

minifiée, 88 caractères: xxx

ou si vous voulez suivre de nouvelles lignes, 85 caractères: < / p> xxx


6 commentaires

Ah, très bien! Bien que je ne sois pas sûr à 100% sur l'utilisation de appliquer . Il y a une limite difficile de quelque chose comme 2 ** 19 arguments à n'importe quelle fonction (à Firefox, de toute façon) et je pense que cela pourrait avoir à faire plus qu'un peu de travail supplémentaire déballant le tableau dans la zone d'argumentation. Je ne m'attends pas à ce que mes matrices soient que longtemps, cependant, et la brièveté est belle.


Je l'ai testé juste (en Firebug), cela a fonctionné jusqu'à environ 12 * 2 ** 20 chiffres ici. Et ce n'était même pas une limite difficile, cela a juste indiqué que le quota d'espace de pile de script était épuisé.


Combien de temps cela prend-il? Pouvez-vous faire du temps nos différentes méthodes avec de grandes matrices d'octets?


@Gabe: hah, juste fini de le faire avec un tableau de 2 ** 23 entrées. J'ai chronométré chaque 5 fois en Firebug, jeté le plus bas et le plus haut et a pris la moyenne des 3 restants. Mon premier prend environ 6 secondes. Votre premier prend environ 5,8, votre seconde environ 5.3, votre troisième prend environ 2,7, et celui-ci environ 0,9 seconde.


Agréable! J'ai pensé que mapper ou appliquer serait le meilleur, c'est pourquoi j'ai évoqué cette réponse mais pas votre autre.


Très cool, mais vous utilisez deux variables dans les données non minifiantes et D, quand elles devraient en être une.