2009-07-28 10 views
22

Czy istnieje naprawdę prosta technika kompresji dla ciągów o długości do około 255 znaków (tak, kompresuję URLs)?Naprawdę prosta kompresja krótkich ciągów znaków

Nie jestem zainteresowany siłą kompresji - szukam czegoś, co działa bardzo dobrze i jest szybkie do wdrożenia. Chciałbym czegoś prostszego niż SharpZipLib: coś, co można zaimplementować za pomocą kilku krótkich metod.

+0

Dlaczego? Prawdopodobnie jest lepszy sposób robienia tego, o co prosisz. –

+2

"Dlaczego" jest z pewnością dobrą odpowiedzią. Jednak, na marginesie, kodowanie Huffmana działa doskonale dla prostej kompresji tekstu bez konieczności uciekania się do zewnętrznych bibliotek i kompresji LZW. –

+2

możliwy duplikat [najlepszego algorytmu kompresji dla krótkich łańcuchów tekstowych] (http://stackoverflow.com/questions/1138345/best-compression-algorithm-for-short-text-strings) –

Odpowiedz

20

Myślę, że kluczową kwestią jest tutaj „Dlaczego chcesz skompresować adresy URL?

Próbując skrócić długie adresy URL do paska adresu?

Lepsze przechowywanie oryginalnego adresu URL gdzieś (baza danych, plik tekstowy ...) wraz z hashcode części bez domeny (MD5 jest w porządku). Możesz wtedy mieć prostą stronę (lub jakiś moduł HTTP, jeśli czujesz się krzykliwie), aby odczytać MD5 i wyszukać prawdziwy adres URL. Oto jak działa TinyURL i inni.

Na przykład:

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

Może być zwarte do:

http://mydomain.com/2d4f1c8a 

Korzystanie z biblioteki kompresji to nie będzie działać. Ciąg zostanie skompresowany do krótszej reprezentacji binarnej, ale konwersja z powrotem na ciąg znaków, który musi być ważny jako część adresu URL (na przykład Base64), zaneguje jakąkolwiek korzyść uzyskaną z kompresji.

Przechowywanie partii adresów URL w pamięci lub na dysku?

Użyj wbudowanej biblioteki kompresji w System.IO.Compression lub bibliotece ZLib, która jest prosta i niewiarygodnie dobra. Ponieważ będziesz przechowywać dane binarne, skompresowane dane wyjściowe będą w porządku, tak jak jest.Musisz ją zdekompresować, aby użyć go jako adresu URL.

+7

To nie jest odpowiedź na pytanie. Co jeśli nie masz gdzie przechowywać hashtable? – endolith

+0

@endolith - Punkt jest kompresją ciągów, nie pomoże ci tutaj, odnosząc go tylko do skrótu lub podobnego. Zobacz odpowiedź Cheeso na przykładowe kompresje z prawdziwego świata, które są dłuższe i równie długie w oryginale po przekonwertowaniu z powrotem na prawidłowe adresy URL. Zawsze masz "gdzieś", aby przechowywać hasz. Twórz kod w swoim kodzie przekierowania adresu URL, jeśli naprawdę masz "nigdzie", aby go zapisać! – badbod99

+1

Nie zawsze masz gdzie przechowywać hashtable, i nie zawsze powoduje to wydłużenie adresu URL. http://en.wikipedia.org/wiki/Data_URI_scheme, na przykład – endolith

1

Jaki jest twój cel?

+0

Nie dotyczy to siły kompresji - jestem szukanie czegoś, co działa bardzo dobrze i jest szybkie do wdrożenia. Czy możesz wskazać mi base64? – cbp

+6

Base64 niczego nie skompresuje :) –

+0

@ Grant Jon: Dokładnie. Base64 był głupią sugestią. Działałby tylko po skompresowaniu, aby uzyskać coś, co (być może) jest mniejsze, ale nadal ascii. Usunąłem wszystkie ślady sugestii. – peSHIr

0

Zacznę od wypróbowania jednej z istniejących (wolnych lub otwartych źródeł) bibliotek zip, np. http://www.icsharpcode.net/OpenSource/SharpZipLib/

pocztowy powinien działać dobrze dla ciągów tekstowych, a nie jestem pewien, czy warto realizacji algorytmu kompresji yourserlf ....

0

Czy próbowałeś już użyć gzip?

Nie mam pojęcia, czy działałby skutecznie z tak krótkimi łańcuchami, ale powiedziałbym, że to prawdopodobnie najlepszy zakład. Biblioteka

12

Zgodnie z sugestią podaną w artykule the accepted answer, użycie kompresji danych nie działa na rzecz skracania ścieżek adresów URL, które są już dość krótkie.

DotNetZip ma klasę DeflateStream, która udostępnia metodę statyczną (Udostępnione w VB): CompressString. Jest to jednoliniowy sposób kompresji ciągu znaków przy użyciu DEFLATE (RFC 1951). Implementacja DEFLATE jest w pełni kompatybilna z System.IO.Compression.DeflateStream, ale DotNetZip kompresuje lepiej. Oto w jaki sposób można go używać:

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); 
    } 
} 

Używając tego kodu, oto wyniki moich badań:

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

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

Więc można zobaczyć „skompresowany” tablicę bajtów, gdy reprezentowana w hex, jest dłuższy niż oryginał, około 2 razy dłuższy. Powód jest taki, że bajt szesnastkowy to właściwie 2 znaki ASCII.

Można to w pewnym stopniu skompensować, używając base-62, zamiast base-16 (hex) do przedstawienia liczby. W takim przypadku a-z i A-Z są również cyframi, co daje 0-9 (10) + a-z (+26) + A-Z (+26) = 62 całkowite cyfry. To znacznie skróciłoby produkcję. Nie próbowałem tego. jeszcze.


EDIT
Ok testowane baza-62 kodera. Skraca łańcuch szesnastkowy o około połowę. Pomyślałem, że zmniejszy to do 25% (62/16 = ~ 4), ale myślę, że tracę coś z dyskretyzacją. W moich testach wynikowy łańcuch zakodowany w bazie 62 jest mniej więcej tej samej długości co pierwotny URL. Zatem nie, używanie kompresji, a następnie kodowania base-62 nadal nie jest dobrym podejściem. naprawdę potrzebujesz wartości hash.

+0

Używanie hexa jest dość głupie, nie jest to wcale gęsty format. Użycie base64 lub nawet base85 i zastąpienie nieprawidłowych znaków przez poprawne (ponowne odejście zajmuje miejsce) z pewnością zmniejszy wydajność. Nie tak bardzo jak twierdzisz, matematyka jest wyłączona. Oczywiście im krótszy URI, tym mniejsza kompresja, jakiej można się spodziewać, a także ma znaczenie kontekst. –

0

Można użyć korekta algorytmu bezpośrednio, bez żadnych nagłówków sum kontrolnych lub stopek, jak opisano w tej kwestii: Python: Inflate and Deflate implementations

To skraca URL 4100 znaków do 1270 znaków base64, moim teście, pozwalając, aby zmieścić Limit IE 2000.

Oto przykład 4000-character URL, którego nie można rozwiązać za pomocą hashtable, ponieważ aplet może istnieć na dowolnym serwerze.

Powiązane problemy