JavaScript中的字符串压缩

Bam*_*bax 33 javascript lossless-compression google-chrome-extension

我正在寻找一个JavaScript函数,给定一个字符串返回一个压缩(更短)的字符串.

我正在开发一个Chrome网络应用程序,可以将长字符串(HTML)保存到本地数据库.出于测试目的,我试图压缩存储数据库的文件,并且缩小了五倍,所以我认为如果我压缩存储的东西,它将有助于保持数据库更小.

我在JavaScript中找到了LZSS的实现:http://code.google.com/p/u-lzss/("U-LZSS").

当我使用简短的示例字符串(解码===编码)"手动"测试它时它似乎有效,而且它在Chrome中也相当快.但是当给出大弦(100 ko)时,它似乎会混乱或混合弦的后半部分.

是否有可能U-LZSS期望短字符串并且不能处理更大的字符串?是否可以调整一些参数以移动上限?

pie*_*oxy 30

我刚刚发布了一个专门为此目的量身定制的小型LZW实现,因为现有的实现都没有满足我的需求.

这就是我正在使用的东西,我可能会尝试在某些时候改进库.


Dav*_*own 14

这是我在一个完整的演示中从 LZW 修改的编码(276 字节,函数 en)和解码(191 字节,函数 de)函数。互联网上没有比我在这里给你的更小或更快的例程。

function en(c){var x='charCodeAt',b,e={},f=c.split(""),d=[],a=f[0],g=256;for(b=1;b<f.length;b++)c=f[b],null!=e[a+c]?a+=c:(d.push(1<a.length?e[a]:a[x](0)),e[a+c]=g,g++,a=c);d.push(1<a.length?e[a]:a[x](0));for(b=0;b<d.length;b++)d[b]=String.fromCharCode(d[b]);return d.join("")}

function de(b){var a,e={},d=b.split(""),c=f=d[0],g=[c],h=o=256;for(b=1;b<d.length;b++)a=d[b].charCodeAt(0),a=h>a?d[b]:e[a]?e[a]:f+c,g.push(a),c=a.charAt(0),e[o]=f+c,o++,f=a;return g.join("")}

var compressed=en("http://www.ScriptCompress.com - Simple Packer/Minify/Compress JavaScript Minify, Fixify & Prettify 75 JS Obfuscators In 1 App 25 JS Compressors (Gzip, Bzip, LZMA, etc) PHP, HTML & JS Packers In 1 App PHP Source Code Packers Text Packer HTML Packer or v2 or v3 or LZW Twitter Compress or More Words DNA & Base64 Packer (freq tool) or v2 JS JavaScript Code Golfer Encode Between Quotes Decode Almost Anything Password Protect Scripts HTML Minifier v2 or Encoder or Escaper CSS Minifier or Compressor v2 SVG Image Shrinker HTML To: SVG or SVGZ (Gzipped) HTML To: PNG or v2 2015 JS Packer v2 v3 Embedded File Generator Extreme Packer or version 2 Our Blog DemoScene JS Packer Basic JS Packer or New Version Asciify JavaScript Escape JavaScript Characters UnPacker Packed JS JavaScript Minify/Uglify Text Splitter/Chunker Twitter, Use More Characters Base64 Drag 'n Drop Redirect URL DataURI Get Words Repeated LZMA Archiver ZIP Read/Extract/Make BEAUTIFIER & CODE FIXER WHAK-A-SCRIPT JAVASCRIPT MANGLER 30 STRING ENCODERS CONVERTERS, ENCRYPTION & ENCODERS 43 Byte 1px GIF Generator Steganography PNG Generator WEB APPS VIA DATAURL OLD VERSION OF WHAK PAKr Fun Text Encrypt Our Google");
var decompressed=de(compressed);

document.writeln('<hr>'+compressed+'<hr><h1>'+compressed.length+' characters versus original '+decompressed.length+' characters.</h1><hr>'+decompressed+'<hr>');
Run Code Online (Sandbox Code Playgroud)

  • 您的代码因 UTF-8 字符而失败。只要在输入字符串上贴一个笑脸,解压后就乱了。您对这些缺乏支持可能是您的压缩比比我的好的原因。 (3认同)

4es*_*n0k 7

看来,有一个压缩/解压缩API的提议:https : //github.com/wicg/compression/blob/master/explainer.md

根据https://blog.chromium.org/2019/12/chrome-80-content-indexing-es-modules.html上的博客文章,它在 Chrome 80(现在处于 Beta 版)中实现。

我不确定我是否在流和字符串之间进行了良好的转换,但这是我尝试使用新 API:

function compress(string, encoding) {
  const byteArray = new TextEncoder().encode(string);
  const cs = new CompressionStream(encoding);
  const writer = cs.writable.getWriter();
  writer.write(byteArray);
  writer.close();
  return new Response(cs.readable).arrayBuffer();
}

function decompress(byteArray, encoding) {
  const cs = new DecompressionStream(encoding);
  const writer = cs.writable.getWriter();
  writer.write(byteArray);
  writer.close();
  return new Response(cs.readable).arrayBuffer().then(function (arrayBuffer) {
    return new TextDecoder().decode(arrayBuffer);
  });
}

const test = "http://www.ScriptCompress.com - Simple Packer/Minify/Compress JavaScript Minify, Fixify & Prettify 75 JS Obfuscators In 1 App 25 JS Compressors (Gzip, Bzip, LZMA, etc) PHP, HTML & JS Packers In 1 App PHP Source Code Packers Text Packer HTML Packer or v2 or v3 or LZW Twitter Compress or More Words DNA & Base64 Packer (freq tool) or v2 JS JavaScript Code Golfer Encode Between Quotes Decode Almost Anything Password Protect Scripts HTML Minifier v2 or Encoder or Escaper CSS Minifier or Compressor v2 SVG Image Shrinker HTML To: SVG or SVGZ (Gzipped) HTML To: PNG or v2 2015 JS Packer v2 v3 Embedded File Generator Extreme Packer or version 2 Our Blog DemoScene JS Packer Basic JS Packer or New Version Asciify JavaScript Escape JavaScript Characters UnPacker Packed JS JavaScript Minify/Uglify Text Splitter/Chunker Twitter, Use More Characters Base64 Drag 'n Drop Redirect URL DataURI Get Words Repeated LZMA Archiver ZIP Read/Extract/Make BEAUTIFIER & CODE FIXER WHAK-A-SCRIPT JAVASCRIPT MANGLER 30 STRING ENCODERS CONVERTERS, ENCRYPTION & ENCODERS 43 Byte 1px GIF Generator Steganography PNG Generator WEB APPS VIA DATAURL OLD VERSION OF WHAK PAKr Fun Text Encrypt Our Google";

async function testCompression(text, encoding = 'deflate') {
  console.log(encoding + ':');
  console.time('compress');
  const compressedData = await compress(text, encoding);
  console.timeEnd('compress');
  console.log('compressed length:', compressedData.byteLength, 'bytes');
  console.time('decompress');
  const decompressedText = await decompress(compressedData, encoding);
  console.timeEnd('decompress');
  console.log('decompressed length:', decompressedText.length, 'characters');
  console.assert(text === decompressedText);
}

(async function () {
  await testCompression(test, 'deflate');
  await testCompression(test, 'gzip');
}());
Run Code Online (Sandbox Code Playgroud)


650*_*502 5

对我来说,使用UTF-8作为目标来压缩字符串似乎是不合理的……看起来只是在寻找麻烦。我认为最好减少一些压缩,并使用纯7位ASCII作为目标。

在一个有趣的4 KB JavaScript演示玩具中,我写了一个有趣的编码,用于压缩结果的编码,该编码将四个二进制字节存储到从85个字符的ASCII子集中选择的五个字符中,可以嵌入JavaScript字符串(85 ^ 5)略大于8 ^ 4,但仍符合JavaScript整数的精度)。这使得压缩数据例如对于JSON安全,而无需任何转义。

  • 您的回答很好,但是在JavaScript中没有UTF-8或任何7位ASCII。每个字符串都以UTF-16内部编码,这就是所有客户端数据库将存储的内容。请注意,这不适用于JavaScript文件的大小,而仅适用于内存(或String对象)获取的localStorage中的大小。 (2认同)
  • @ 6502 localStorage中的限制是根据字符而不是字节来定义的。因此,到底使用UTF-8还是UTF-16并不重要。您可以存储250万个字符(在Firefox上为5M),并且使用整个UTF-16空间仍然可以提供更多数据。 (2认同)

Bam*_*bax 5

在Piskvor的建议下,我测试了在这个问题的答案中找到的代码:Gzip的JavaScript实现 (最高投票答案:LZW实现),并发现:

  1. 有用
  2. 它将数据库的大小减少了两倍

......小于5但比没有好!所以我用过它.

(我希望我能接受Piskvor的回答,但这只是一个评论).

  • Bambax - 您可以随时要求@Piskvor做出答案,以便您接受. (3认同)