【问题标题】:javascript string compression with localStorage使用 localStorage 进行 javascript 字符串压缩
【发布时间】:2011-10-15 11:07:31
【问题描述】:

我在一个项目中使用localStorage,它需要存储很多 数据,主要是int、bool 和string 类型。我知道 javascript 字符串是 unicode,但是当存储在 localStorage 中时,它们会保持 unicode 吗?如果是这样,有没有办法可以压缩字符串以使用 unicode 字节中的所有数据,或者我应该只使用 base64 并减少压缩?所有数据都将存储为一个大字符串。

编辑:现在我想起来了,base64 根本不会做太多压缩,数据已经在 base 64 中,a-zA-Z0-9 ;: 是 65 个字符。

【问题讨论】:

  • 我认为建议中没有。我认为每个实现都可能不同。
  • localStorage 是 unicode 格式的吗?还是那个javascript是?我很确定 javascript 字符串是 unicode,但我不知道 localstorage 是否是
  • 我认为您存储在localStorage 中的所有内容都应该在存储时返回。但没人知道我一直在使用 base64 编码。
  • 我用包含、unicode hiragana A 的字符串测试了本地存储,但它没有保存值(在谷歌浏览器中)。如果它不是 unicode 那会是什么? ASCII?拉丁语?
  • 我很想知道是否有任何 Javascript 压缩算法可以与 localStorage 一起使用。我正在寻找一种快速的东西,它可以对主要是文本的数据进行一些压缩。

标签: javascript unicode compression base64 local-storage


【解决方案1】:

您可以编码为 Base64,然后实现简单的无损压缩算法,例如游程编码或 Golomb 编码。这不应该太难做,可能会给你一点压力。

Golomb encoding

我还找到了 JsZip。我猜你可以检查代码,只使用算法,如果它是兼容的。

希望这会有所帮助。

http://jszip.stuartk.co.uk/

【讨论】:

  • 我尝试了几种无损编码,但它们经常使用 UTF-16 字符,这与 localStorage 不兼容。如果你对内容进行base64编码,当原始内容是ASCII时,你最终会得到比原始内容更大的内容。不过,我会检查 Golomb 编码和 JSZip,我还没有尝试过它们。它可能会产生良好的效果。
  • 这是另一个可能感兴趣的帖子。不确定它是否符合您的用例,但仍然很有趣:sean.co.uk/a/webdesign/javascript_string_compression.shtm
  • 我完成了 Golomb 编码的尝试,到目前为止,它对真实数据的效果很好(大约 5% 的压缩率并且仍然可读)。考虑到算法的速度,这是迄今为止我见过的最好的。
  • Base64 为您的字符串大小增加了 30%,您确定压缩能够弥补这一点吗?
【解决方案2】:

“当存储在 localStorage 中时,它们是否保持 unicode?”

Web Storage working draft 将本地存储值定义为 DOMString。 DOMStrings are defined 使用 UTF-16 encoding 作为 16 位单元的序列。所以是的,它们仍然是 Unicode。

有没有办法可以压缩字符串以使用 unicode 字节中的所有数据...

“Base32k”编码应该为每个字符提供 15 位。 base32k 类型编码利用了 UTF-16 字符中的完整 16 位,但会丢失一点以避免在双字字符上出错。如果您的原始数据采用 base64 编码,则每个字符仅使用 6 位。将这 6 位编码为 base32k 应将其压缩为原始大小的 6/15 = 40%。请参阅http://lists.xml.org/archives/xml-dev/200307/msg00505.htmlhttp://lists.xml.org/archives/xml-dev/200307/msg00507.html

为了进一步减小大小,您可以将 base64 字符串解码为完整的 8 位二进制文​​件,使用一些已知的压缩算法(例如,参见 javascript implementation of gzip)对其进行压缩,然后对压缩后的输出进行 base32k 编码。

【讨论】:

  • +1 用于参考我将要参考的所有规范并更进一步。
  • 但是为什么あ不保存(在谷歌浏览器中,可能是浏览器是错误的吗?)?不过感谢 base32k!
  • 是什么让你说あ不保存?试试jsbin.com/odadig/4/edit#javascript,html,live。似乎可以在 Windows 上与 Chrome 15 一起正常工作。进行实验时,请确保使用 Unicode 编码保存 html 文件,例如UTF8.
  • 这个 JS 库中的 compressToUTF16 和 decompressFromUTF16 函数基本上完成了这个答案所描述的(LZW + base32k):pieroxy.net/blog/pages/lz-string/index.html
【解决方案3】:

This Stackoverflow Question 有一个可能有帮助的答案。有一个 JavaScript 压缩库的链接。

【讨论】:

    【解决方案4】:

    我最近不得不在 localStorage 中保存巨大的 JSON 对象。

    首先,是的,它们确实保持 unicode。但是不要尝试将对象之类的东西直接保存到本地存储中。它必须是一个字符串。

    在将对象转换为字符串之前,我使用了一些压缩技术(在我的情况下似乎效果很好):

    通过执行 (+num).toString(36) 之类的操作,可以将任何以 10 为底的数字转换为以 36 为底的数字。例如,数字 48346942 将是“ss8qm”,即(包括引号)少 1 个字符。添加引号可能实际上会增加字符数。所以数字越大,回报就越好。要将其转换回来,您可以执行类似 parseInt("ss8qm", 36) 的操作。

    如果您使用任何会重复的键存储对象,最好创建一个查找对象,在其中为原始键分配一个缩短的键。因此,举例来说,如果您有:

    {
        name: 'Frank',
        age: 36,
        family: [{
            name: 'Luke',
            age: 14,
            relation: 'cousin'
        }, {
            name: 'Sarah',
            age: 22,
            relation: 'sister'
        }, {
            name: 'Trish',
            age: 31,
            relation: 'wife'
        }]
    }
    

    那么你就可以做到:

    {
        // original w/ shortened keys
        o: {    
            n: 'Frank',
            a: 36,
            f: [{
                n: 'Luke',
                a: 14,
                r: 'cousin'
            }, {
                n: 'Sarah',
                a: 22,
                r: 'sister'
            }, {
                n: 'Trish',
                a: 31,
                r: 'wife'
            }]
        },
    
        // lookup
        l: {
            n: 'name',
            a: 'age',
            r: 'relation',
            f: 'family'
        }
    }
    

    同样,这与大小有关。和重复。就我而言,它工作得非常好。但这取决于主题。

    所有这些都需要一个函数来收缩和一个扩展回来。

    另外,我建议创建一个用于从本地存储中存储和检索数据的类。我跑到那里没有足够的空间。所以写入会失败。其他站点也可能会写入本地存储,这可能会占用一些空间。详情请见this post

    在我构建的类中,我首先尝试使用给定键删除任何项目。然后尝试 setItem。这两行都用 try catch 包裹起来。如果失败,则假定存储已满。然后它将清除 localStorage 中的所有内容,以尝试为其腾出空间。然后,在清除之后,它将再次尝试 setItem。这也包含在 try catch 中。因为如果字符串本身比 localStorage 可以处理的大,它可能会失败。

    编辑:另外,你会遇到很多人提到的 LZW 压缩。我已经实现了,它适用于小字符串。但是对于大字符串,它将开始使用导致数据损坏的无效字符。所以要小心,如果你往那个方向去测试测试测试

    【讨论】:

    • 我对 LZW 压缩得出了相同的结论,它不适用于大字符串。至于存储类,我发现也很有用的是在您存储的密钥上实现过期机制,这样旧密钥就不会永远存在。数字提示非常有用,尤其是在您使用时间戳时。
    【解决方案5】:

    JavaScript 的 Base64 压缩得到了很好的解释 at this blog。使用整个framework时,实现也是available here

    【讨论】:

      猜你喜欢
      • 2013-10-30
      • 2018-11-13
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 1970-01-01
      相关资源
      最近更新 更多