2009-07-28 3 views
22

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

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

+0

Почему? Вероятно, есть лучший способ сделать то, что вы просите. –

+2

«Почему», безусловно, хороший ответ. Однако, как замечание, кодирование Хаффмана отлично подходит для простого сжатия текста без необходимости использования внешних библиотек и сжатия LZW. –

+2

Возможный дубликат [Лучший алгоритм сжатия коротких текстовых строк] (http://stackoverflow.com/questions/1138345/best-compression-algorithm-for-short-text-strings) –

ответ

20

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

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

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

Например:

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

Может быть замкнута на:

http://mydomain.com/2d4f1c8a 

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

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

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

+7

Это не ответ на вопрос. Что делать, если вам некуда хранить хэш-таблицу? – endolith

+0

@endolith - Точка сжатия строк вам не поможет, только привязывая ее к хэшу или тому подобное. См. Ответ Cheeso на примеры сжатия в реальном мире дольше и так же долго в оригинале, когда он преобразуется обратно в действительные URL-адреса. У вас всегда есть «где-то», чтобы сохранить хэш. Жестко закодируйте его в код перенаправления URL, если у вас действительно есть «нигде», чтобы его сохранить! – badbod99

+1

У вас не всегда есть место для хранения хэш-таблицы, и это не всегда делает URL длиннее. http://en.wikipedia.org/wiki/Data_URI_scheme, например – endolith

1

Какую цель?

  • Короткий URL? Попробуйте сократить URL-адреса, такие как http://tinyurl.com/ или http://is.gd/
  • Складские помещения? Проверьте System.IO.Compression. (Или SharpZipLib)
+0

Не касается силы сжатия - я ищет что-то, что работает очень хорошо и быстро реализуется. Можете ли вы указать мне base64? – cbp

+6

Base64 не собирается ничего сжимать :) –

+0

@Jon Grant: Правильно. Base64 был глупым предложением. Будет работать только после фактического сжатия, чтобы получить что-то, что (возможно) меньше, но все равно ascii. Удалили все следы этого предложения. – peSHIr

0

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

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

0

Вы пробовали использовать только gzip?

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

0

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

12

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

DotNetZip имеет класс DeflateStream, который предоставляет метод статического (Shared in VB) CompressString. Это однострочный способ сжатия строки с использованием DEFLATE (RFC 1951). Реализация DEFLATE полностью совместима с System.IO.Compression.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 

Таким образом, вы можете увидеть «сжатый» байтовый массив, при представлении в шестнадцатеричном, длиннее оригинал, примерно в 2 раза. Причина в том, что шестнадцатеричный байт на самом деле является 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 по-прежнему не является хорошим подходом. вы действительно хотите хэш-значение.

+0

Использование hex - довольно глупо, это совсем не плотный формат. Использование base64 или даже base85 и замена недопустимых символов правильными (ускорение пробела занимает пространство), безусловно, уменьшит выход. Не так много, как вы утверждаете, ваша математика отключена. Конечно, чем короче URI, тем меньше сжатия вы можете ожидать, и это также имеет значение для контекста. –

0

Вы можете использовать выкачать алгоритм непосредственно, без каких-либо заголовков контрольных сумм или колонтитулы, как описано в этом вопросе: Python: Inflate and Deflate implementations

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

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

Смежные вопросы