Очень простое сжатие коротких строк

есть ли действительно простой метод сжатия для строк длиной до 255 символов (да, я сжимаю URLs)?

меня не волнует сила сжатия - я ищу что-то, что работает очень хорошо и быстро реализовать. Я хотел бы что-то проще, чем SharpZipLib: что-то, что может быть реализовано несколько коротких методов.

9 ответов


Я думаю, что ключевой вопрос здесь -"почему вы хотите сжать URL-адреса?"

попытка сократить длинные URL-адреса для адресной строки?

вам лучше сохранить исходный URL-адрес где-нибудь (база данных, текстовый файл ...) наряду с хэш-кодом недоменной части (MD5 в порядке). Затем у вас может быть простая страница (или какой-то HTTPModule, если вы чувствуете себя кричащим), чтобы прочитать MD5 и найти реальный URL. Это как TinyURL и другие работа.

например:

http://mydomain.com/folder1/folder2/page1.aspx

может быть закорочена на:

http://mydomain.com/2d4f1c8a

использование библиотеки сжатия для этого не будет работать. Строка будет сжата в более короткое двоичное представление, но преобразование этого обратно в строку, которая должна быть действительной как часть URL (например, Base64), сведет на нет любую выгоду, полученную от сжатия.

хранение большого количества URL-адресов в памяти или на диске?

использовать встроенный сжатие библиотеки в системе.ИО.Сжатие или библиотека ZLib, которая проста и невероятно хороша. Поскольку вы будете хранить двоичные данные, сжатый вывод будет в порядке как есть. Вам нужно распаковать его, чтобы использовать его в качестве URL.


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

DotNetZip имеет класс DeflateStream, который предоставляет статический (Общий в VB)CompressString метод. Это однострочный способ сжатия строки с помощью DEFLATE (RFC 1951). Реализация DEFLATE полностью совместима с система.ИО.Сжатие.DeflateStream, но DotNetZip сжимается лучше. Вот как вы можете использовать это:

string[] orig = {
    "folder1/folder2/page1.aspx",
    "folderBB/folderAA/page2.aspx",
};
public void Run()
{
    foreach (string s in orig)
    {
        System.Console.WriteLine("original    : {0}", s);
        byte[] compressed = DeflateStream.CompressString(s);
        System.Console.WriteLine("compressed  : {0}", ByteArrayToHexString(compressed));
        string uncompressed = DeflateStream.UncompressString(compressed);
        System.Console.WriteLine("uncompressed: {0}\n", uncompressed);
    }
}

используя этот код, вот мои результаты теста:

original    : folder1/folder2/page1.aspx
compressed  : 4bcbcf49492d32d44f03d346fa0589e9a9867a89c5051500
uncompressed: folder1/folder2/page1.aspx

original    : folderBB/folderAA/page2.aspx
compressed  : 4bcbcf49492d7272d24f03331c1df50b12d3538df4128b0b2a00
uncompressed: folderBB/folderAA/page2.aspx

таким образом, вы можете видеть, что "сжатый" массив байтов, представленный в hex, длиннее оригинала, около 2x. Причина в том, что шестнадцатеричный байт на самом деле 2 символа ASCII.

вы можете несколько компенсировать это, используя base-62 вместо base-16 (hex) для представления числа. В этом случае A-z и A-Z также являются цифрами, дает вам 0-9 (10) + a-z (+26) + A-Z (+26) = 62 полных цифры. Это значительно сократит объем производства. Я не пробовал. еще.


редактировать
Хорошо, я протестировал кодировщик Base-62. Он сокращает шестнадцатеричную строку примерно наполовину. Я полагал, что это сократит его до 25% (62/16 =~ 4), но я думаю, что теряю что-то с дискретизацией. В моих тестах результирующая строка в кодировке base-62 имеет ту же длину, что и исходный URL-адрес. Итак, нет, используя сжатие, а затем кодирование base-62 по-прежнему не является хорошим подходом. вы действительно хотите хэш-значение.


Я бы предложил посмотреть в Система.ИО.Пространство Имен Сжатия. Есть статья о CodeProject что может помочь.


какова ваша цель?

  • более короткий URL? Попробуйте url shorteners как http://tinyurl.com/ или http://is.gd/
  • места для хранения? Проверьте систему.ИО.Сжатие. (Или SharpZipLib)

Я бы начал с попытки одной из существующих (бесплатных или с открытым исходным кодом) zip-библиотек, например http://www.icsharpcode.net/OpenSource/SharpZipLib/

Zip должен хорошо работать для текстовых строк, и я не уверен, стоит ли реализовывать алгоритм сжатия yourserlf....


вы пробовали просто с помощью С помощью gzip?

Не знаю, будет ли он эффективно работать с такими короткими строками, но я бы сказал, что это, вероятно, ваш лучший выбор.


библиотека с открытым исходным кодом SharpZipLib проста в использовании и предоставит вам инструменты сжатия


вы можете использовать алгоритм дефляции напрямую, без каких-либо контрольных сумм или нижних колонтитулов, как описано в этом вопросе: Python: надувать и сдувать реализации

это сокращает URL-адрес 4100 символов до 1270 символов base64 в моем тесте, позволяя ему вписываться в ограничение 2000 IE.

вот пример 4000-символьный URL, который не может быть решен с помощью хэш-таблицы, так как апплет может существовать на любом сервере.


Я только что создал схему сжатия, которая нацелена на URL-адреса и достигает сжатия около 50% (по сравнению с представлением base64 исходного текста URL).

см.http://blog.alivate.com.au/packed-url/