Javascript 如何压缩字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3640357/
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
How to compress a string?
提问by FurtiveFelon
I would like to have a reversible compression for a type of string so that i can include it in URLs without keeping track of what it refers to. The string i would like to compress is SVG path string, here is a short primer: http://apike.ca/prog_svg_paths.html
我想对一种类型的字符串进行可逆压缩,以便我可以将它包含在 URL 中,而无需跟踪它所指的内容。我想压缩的字符串是 SVG 路径字符串,这是一个简短的入门:http: //apike.ca/prog_svg_paths.html
Basically, the string contains a character, followed by arbitrary number of integers, then another character followed by arbitrary number of integers and so on.
基本上,字符串包含一个字符,后跟任意数量的整数,然后是另一个字符,后跟任意数量的整数,依此类推。
If anyone knows of a good resource for this, it would be much appreciated!
如果有人知道这方面的好资源,将不胜感激!
Jason
杰森
回答by olliej
Many compression algorithms are well documented, a couple even have js implementations:
许多压缩算法都有详细记录,有几个甚至有 js 实现:
GZipA common (reasonably) good compression algorithm, I know there's a JS impl, i'm just hunting the URL
LZWAnother question points to an LZW implementation in JS
Arithmetic coding(i did this, but the model it uses is stupid so doesn't achieve the best compression rates it could)
回答by pp19dd
Sounds like you might benefit from single and double RLE compression.
听起来您可能会从单 RLE 和双 RLE 压缩中受益。
A primer on this can be seen here:
可以在此处查看有关此内容的入门:
http://pp19dd.com/2011/10/query-string-limits-encoding-hundreds-of-checkboxes-with-rle/#demo
http://pp19dd.com/2011/10/query-string-limits-encoding-hundreds-of-checkboxes-with-rle/#demo
The library should be flexible enough to modify your compression pattern to something more preferable. The writeup explains how this works; might be a good start to optimize your SVG case.
该库应该足够灵活,可以将您的压缩模式修改为更可取的。这篇文章解释了这是如何工作的;可能是优化 SVG 案例的良好开端。
回答by pepkin88
You could try Huffman compression. Number of different chars is 20-30, and if the string is long, compression should be effective.
你可以试试霍夫曼压缩。不同字符数为20-30,如果字符串很长,压缩应该有效。
回答by Simon Hutchison
The following solution returns a compressed Base64 encoded string.
以下解决方案返回压缩的 Base64 编码字符串。
Create a file called zip.js with the code below and then see usage below that.
使用下面的代码创建一个名为 zip.js 的文件,然后查看下面的用法。
// Apply LZW-compression to a string and return base64 compressed string.
export function zip (s) {
try {
var dict = {}
var data = (s + '').split('')
var out = []
var currChar
var phrase = data[0]
var code = 256
for (var i = 1; i < data.length; i++) {
currChar = data[i]
if (dict[phrase + currChar] != null) {
phrase += currChar
} else {
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
dict[phrase + currChar] = code
code++
phrase = currChar
}
}
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
for (var j = 0; j < out.length; j++) {
out[j] = String.fromCharCode(out[j])
}
return utoa(out.join(''))
} catch (e) {
console.log('Failed to zip string return empty string', e)
return ''
}
}
// Decompress an LZW-encoded base64 string
export function unzip (base64ZippedString) {
try {
var s = atou(base64ZippedString)
var dict = {}
var data = (s + '').split('')
var currChar = data[0]
var oldPhrase = currChar
var out = [currChar]
var code = 256
var phrase
for (var i = 1; i < data.length; i++) {
var currCode = data[i].charCodeAt(0)
if (currCode < 256) {
phrase = data[i]
} else {
phrase = dict[currCode] ? dict[currCode] : oldPhrase + currChar
}
out.push(phrase)
currChar = phrase.charAt(0)
dict[code] = oldPhrase + currChar
code++
oldPhrase = phrase
}
return out.join('')
} catch (e) {
console.log('Failed to unzip string return empty string', e)
return ''
}
}
// ucs-2 string to base64 encoded ascii
function utoa (str) {
return window.btoa(unescape(encodeURIComponent(str)))
}
// base64 encoded ascii to ucs-2 string
function atou (str) {
return decodeURIComponent(escape(window.atob(str)))
}
Usage:
用法:
import { zip, unzip } from './zip'
// Zip a string
const str = 'zip it'
const base64CompressedString = zip(str)
// Zip an object
const obj = { a: 123, b: 'zipit' }
const base64CompressedString = zip(JSON.stringify(obj))
// Unzip the base64 compressed string back to an object.
const originalObject = JSON.parse(unzip(base64CompressedString))
BTW... if you're concerned about escape/unescape being depreciated consider a polyfill
顺便说一句......如果你担心逃避/逃避被贬值,考虑一个polyfill

