Подтвердить что ты не робот

Сжатие строки javascript с помощью localStorage

Я использую localStorage в проекте, и ему нужно будет хранить много данных, в основном типа int, bool и string. Я знаю, что строки javascript являются unicode, но когда они хранятся в localStorage, они остаются в unicode? Если это так, есть ли способ сжать строку, чтобы использовать все данные в байтах юникода, или я должен просто использовать base64 и иметь меньше сжатия? Все данные будут сохранены в виде одной большой строки.

EDIT: теперь, когда я думаю об этом, base64 вообще не будет делать никакого сжатия, данные уже находятся в базе 64, a-zA-Z0-9 ;: составляет 65 символов.

4b9b3361

Ответ 1

", если они хранятся в localStorage, они остаются в unicode?"

рабочий проект Web Storage определяет локальные значения хранилища как DOMString. DOMStrings определены как последовательности 16-битных единиц с помощью UTF- 16 ". Так что да, они остаются Юникодом.

есть способ, которым я мог бы сжать строку, чтобы использовать все данные в байтах юникода... ?

"Base32k" кодировка должна давать вам 15 бит на символ. Кодировка base32k использует преимущества 16-битных символов в символах UTF-16, но теряет бит, чтобы избежать отключения символов двойного слова. Если исходные данные закодированы в base64, он использует только 6 бит на символ. Кодирование этих 6 бит в base32k должно сжать его до 6/15 = 40% от его первоначального размера. См. http://lists.xml.org/archives/xml-dev/200307/msg00505.html и http://lists.xml.org/archives/xml-dev/200307/msg00507.html.

Для дальнейшего уменьшения размера вы можете декодировать свои строки base64 в их полный 8-битный двоичный код, сжать их с помощью известного алгоритма сжатия (например, см. javascript-реализация gzip), а затем base32k кодирует сжатый вывод.

Ответ 2

Вы можете кодировать Base64, а затем реализовывать простой алгоритм сжатия без потерь, такой как кодирование по длине или кодирование Golomb. Это не должно быть слишком сложно сделать и может дать вам немного омрачения.

Кодировка Голомба

Я также нашел JsZip. Я думаю, вы можете проверить код и использовать его только в том случае, если он совместим.

Надеюсь, что это поможет.

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

Ответ 3

Недавно мне пришлось сохранять огромные объекты JSON в localStorage.

Во-первых, да, они остаются юникодом. Но не пытайтесь сэкономить что-то вроде объекта прямо на локальном хранилище. Это должна быть строка.

Вот некоторые методы сжатия, которые я использовал (что, казалось, хорошо работает в моем случае), перед преобразованием моего объекта в строку:

Любые числа могут быть преобразованы из базы 10 в базу из 36, выполняя что-то вроде (+ num).toString(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'
    }
}

Опять же, это окупается размером. И повторение. В моем случае это работало очень хорошо. Но это зависит от предмета.

Для всех этих функций требуется сокращение функции, а одно - для возврата назад.

Кроме того, я бы рекомендовал создать класс, который используется для хранения и извлечения данных из локального хранилища. Я столкнулся с тем, что не хватало места. Таким образом, записи потерпят неудачу. Другие сайты также могут записывать на локальное хранилище, которое может отнять часть этого пространства. Подробнее см. этот пост.

Что я сделал, в классе, который я построил, была первая попытка удалить любой элемент с данным ключом. Затем попробуйте setItem. Эти две строки завернуты с помощью try catch. Если он терпит неудачу, он предполагает, что хранилище заполнено. Затем он очистит все в localStorage, пытаясь освободить место для этого. Затем, после ясной, попытается снова установить значение. Это тоже завернуто в попытку поймать. Так как это может привести к сбою, если сама строка больше, чем может обрабатывать localStorage.

EDIT: Кроме того, вы столкнетесь с компрессией LZW, о которой многие говорят. Я реализовал это, и он работал для небольших строк. Но с большими строками он начнет использовать недопустимые символы, которые приведут к повреждению данных. Так что будьте осторожны, и если вы пойдете в этом направлении, тестовый тестовый тест