Interesuje mnie kodowanie łańcucha, który mam i jestem ciekawy, czy istnieje rodzaj kodowania, który może być użyty, który będzie zawierał tylko znaki alfanumeryczne i najlepiej skróciłby liczbę znaków potrzebnych do przedstawienia łańcucha.
Do tej pory zastanawiałem się nad użyciem do tego kodowania Base64, ale wydaje się, że mój łańcuch jest dłuższy i czasami zawiera to, ==
czego chciałbym uniknąć. Przykład:
nazwa testu | 120101
staje się
dGVzdCBuYW1lfDEyMDEwMQ ==
który ma od 16 do 24 znaków i zawiera znaki niealfanumeryczne.
Czy ktoś wie o innym rodzaju kodowania, którego mógłbym użyć, który spełni moje wymagania? Punkty bonusowe, jeśli są wbudowane w platformę .NET lub istnieje biblioteka innej firmy, która wykona kodowanie.
.net
text-encoding
Abe Miessler
źródło
źródło
Odpowiedzi:
Końcowe „=” lub „==” w Base64 jest tylko po to, aby liczba znaków była wielokrotnością 4. Możesz go usunąć, ponieważ zawsze możesz przywrócić go później. Zauważ, że Base64 jest tak zwany, ponieważ używa 64 różnych znaków. Wielkie litery, małe litery i cyfry to 62. Tak więc Base64 używa również „/” i „+”, które mogą, ale nie muszą pasować do twojego rachunku.
Ogólnie rzecz biorąc, jeśli chcesz zakodować dowolne sekwencje bajtów w znaki alfanumeryczne, niekoniecznie istnieje jakieś rozszerzenie długości, ponieważ istnieje 256 możliwych wartości dla bajtu i tylko 62 znaki alfanumeryczne. Czasami nazywa się to zasadą szufladki . Schemat kodowania musi mieć rozszerzenie średniej długości logarytmu 256 / log 62 = 1,344 (średnia dla wszystkich sekwencji bajtów); w przeciwnym razie oznacza to, że niektóre gołębie są gdzieś miażdżone na śmierć i nie odzyskasz ich bez uszkodzenia (co oznacza: dwa różne łańcuchy zakodowane w tym samym, więc dekodowanie nie może działać niezawodnie).
Jest całkiem możliwe, że twoje ciągi nie są dokładnie „sekwencjami jednakowo losowych bajtów”; twoje łańcuchy mają jakieś znaczenie, co oznacza, że nie pojawi się jak najwięcej sekwencji bajtów, ponieważ są one bez znaczenia. Na tej podstawie możesz prawdopodobnie opracować schemat kodowania, który będzie miał krótsze rozszerzenie długości niż standardowy Base64 (lub Base62, jeśli chcesz trzymać się ścisłych znaków alfanumerycznych). Jest to bezstratna kompresja danych . Działa na jasno zdefiniowanym modelu probabilistycznym tego, co może pojawić się jako dane wejściowe.
Podsumowanie: generic schemat kodowania ciągów alfanumerycznych do sekwencji takich, które nie lub mało długość rozszerzenie kiedykolwiek nastąpi, nie może istnieć; jest to matematyczna niemożliwość. Specyficzny schemat dostosowane do rodzaju ciągu wejściowego można oczekiwać można prawdopodobnie istnieć (ale ponieważ nie powiedzieć, jaki rodzaj sznurka można napotkać, nikt nie może pomóc w tej sprawie).
źródło
=
/==
jest uzależniona od długości mającego być wielokrotnością 4. Może będę mógł obejść dla moich potrzebPonowne kodowanie znaków jest zwykle wykonywane, gdy system odbiorczy nie może ich przetworzyć. Na przykład BASE64 reprezentuje dane przy użyciu 6 bitów (2 6 , a więc 64) znaków, które reprezentują dłuższe sekwencje danych (czasami pojawiające się „==” na końcu to dopełnienie do wyrównania). Wynika to z faktu, że plik obrazu w wiadomości e-mail może zawierać 0xFE, a serwer pocztowy będzie niezadowolony z przesyłania tego (lub innego tradycyjnie nie drukującego znaku).
Nie ma kodowania, które „zmniejsza rozmiar”. Kodowanie to tylko odwzorowanie bitów na znak, który reprezentują. To powiedziawszy, ASCII to 7-bitowy zestaw znaków (kodowanie), który często jest przechowywany w 8 bitach przestrzeni. Jeśli ograniczysz zakresy, które akceptujesz, możesz także usunąć znaki kontrolne.
Korzystanie z tej metody oznacza, że musisz zapisywać rzeczy na poziomie bitów, a także gra trochę piekła z szybkością maszyny i instrukcjami, ponieważ wszystkie nowoczesne maszyny mają wyrównania, które są wielokrotnościami 8 bitów. Dlatego na przykład Unicode to UTF-8, UTF-16 i UTF-32.
Jeśli robisz to dla bezpieczeństwa (dlatego opublikowałeś go w Security.SE, prawda?), Po prostu odfiltruj rzeczy i przechowuj je normalnie. Jeśli robisz to, aby zaoszczędzić miejsce, zastanów się, czy cały dodatkowy kod i wolniejszy czas dostępu (ponieważ większość wpisów przekroczy granice adresów) jest warta oszczędności miejsca.
Do tego czasu to fragment kodu kursu CS, w którym musieliśmy przekonwertować ASCII z pamięci 8-bitowej na 7-bitową:
źródło
Możesz skompresować dane za pomocą np. Gzip, bzip2 lub lzma, a następnie uruchomić przez base64, aby ograniczyć używany zestaw znaków. Jest to korzystne tylko w przypadku większych ciągów setek bajtów lub więcej.
źródło
dlaczego nie użyć kompresji LZ? może to być przyzwoity sposób kompresji łańcucha, ale byłby bardziej wydajny w przypadku długich łańcuchów. Jak długi jest ciąg docelowy, który chcesz zakodować?
źródło