[C++/CLI] Kodowanie plików, a szyfrowanie

0

Niby C++, ale jednak CLI, to pozwoliłem sobie tu umieścić temat.
Koduję sobie szyfrowanie algorytmem Vigenere'a (wiki powinna wiedzieć o co chodzi, dla zainteresowanych ;) ) i wszystko działa ok, tak szyfrowanie, jak i deszyfracja. A przynajmniej działa ok dla pewnych plików... Jeśli plik tekstowy, który chcę zaszyfrować, jest w kodowaniu UTF-8, wszystko jest bez problemu, plik po deszyfracji jest w 100% zgodny z plikiem przed szyfrowaniem, czyli ok.
Jednak kiedy próbuję zaszyfrować plik kodowany ANSI, pojawia się problem. Plik jest czytany przez StreamReadera jako plik UTF-8, chociaż zapisany jest w formacie ANSI. Co za tym idzie plik wynikowy też leci do UTF-8, co powoduje róznice w bajtach między plikiem źródłowym a końcowym.
I kombinuję jak to załatwić, żeby działało, ale pomysłów mi brak, a sprawa powoli staje się nagląca.

Aby utworzyć plik wynikowy o takim samym kodowaniu jak plik źródłowy posługuję się taką konstrukcją:

input = gcnew StreamReader(inputName);
currentChar = input->Read();
output = gcnew StreamWriter(outputName, false, input->CurrentEncoding);

Po readzie ze streamReadera powinno już być znane kodowanie. Sprawdzałem, wychodzi utf-8, mimo, że plik zapisany jest w ANSI. A skoro tak, to plik wynikowy też powinien być w ANSI, a wychodzi w utf.
Inna sprawa, że wydaje mi się to lekko pod górkę, takie kombinowanie ze stworzeniem pliku wynikowego o takim samym kodowaniu jak wejściowy, ale cóż, działa dla unicoda, działa dla utf, działa dla Unicoda Big Endian (chociaż wyświetla że to Unicode).

Z przyjemnością przyjmę jakąś dobrą radę, jak sobie z tym poradzić.
Z góry dzięki
Pozdro

0

Automatyczne wykrywanie kodowania działa tylko dla różnych typów Unicode. Dla innych kodowań, a więc i ASCII kodowania nie odgadnie, więc zastosuje domyślne - czyli właśnie UTF8.
Jak to obejść?

input = gcnew StreamReader(inputName, Encoding::ASCII, true);

Przeciążony konstruktor, który pozwala na ustalenie domyślnego kodowania (ASCII), które zostanie zastosowane, jeśli wykrywanie nie zadziała (te wymuszamy odpowiednią wartością trzeciego parametru).

http://msdn.microsoft.com/en-us/library/akzyzwh9.aspx

0

No faktycznie, mogłem przejrzeć porządnie listę konstruktorów...
Teraz rozbijam się znowu o inny problem, kiedy już wykryje ASCII, to sypie się szyfrowanie.
Z pliku:

polskie litery: ąężźć
POLSKIE LITERY: ĄĘŻŹĆ

otrzymuję po szyfrowaniu-deszyfrowaniu:

.-,.kie ,i-e.-: ?????
POLSKIE LITERY: ?????

O ile domyślam się, że polskie litery gubią się, bo tabeli kodowania stosuję Char, które z tego co widziałem w debugu jest sprowadzane do wchar, to nie rozumiem, czemu małe litery zwykłe pozmieniały się na kropki i kreski...
Dalej jednak nie wiem, jak problem objeść. Bo kiedy kodowanie jest wykrywane poprawnie jako ASCII, to zamiast polskich liter czytane są '?'.
Nigdy w sumie więcej z kodowaniami plików nie miałem do czynienia, a uznanie, że program będzie działał tylko dla plików w unicodzie jest średnim rozwiązaniem. Char nie ma chyba możliwości traktowania znaków jako ASCII, domyślnie wszystko łyka jako unicode, mogę co najwyżej do utf32 konwertować.
Z tego co się orientuję, to ANSI nie jest po prostu ASCII, tylko pliki są zapisane w ASCII, ale znaki niektóre traktowane są inaczej, mamy więc te kodowanie iso 88592 czy jakoś tak, windows 1250 i to one ustalają, jak będzie interpretowany znak o wartości przekraczającej podstawowe 128 znaków, tak? Notatnik windowsowy zapewne domyślnie zapisuje pliki ANSI w kodowaniu windows1250. Jednak odczytanie z tego pliku przez program, który wykrywa ASCII daje pytajniki, jakby nie traktowało tego jako windows1250.

Jak nakłonić go do odczytania tego pliku poprawnie? żeby zamiast '?' pojawiły się polskie litery, albo przynajmniej ich odpowiedniki w rozszerzonej tabeli ascii (czyli dla "Ą" bodajże 161)?
I jakiś pomysł, czemu małe litery zmieniają się w kreski, kiedy dla unicode wszystko działa ok? Czy to wynika z zastosowania Charów do porwónywania, które sa unicodowe? Ich też pewno nie da się zmusić żeby były ascii?

E:
dobra, wiem, czemu pojawiają się kreski. Przy szyfrowaniu z kluczem "123" po prostu polskie litery było zamieniane na ęęąś... itd., a potem przy deszyfrowaniu były czytane pytajniki, które zamieniał na znaczki zgodnie z kluczem... czyli wszystko rozbija się o poprawne czytanie polskich liter z pliku, czemu czyta '?' zamiast litery czy jej odpowiednika ascii

E2:
Zmusiłem go, żeby zamiast domyślnego ASCII brał domyślne Windows-1250. Działa. Teraz głowię się raczej nad tym, jak to zautomatyzować, bo dla unicodów i windowsowych ok, ale jak ktoś wrzuci mu iso 8859-2 to już problem, a automagiczne wykrywanie jak widac nie do końca pozytywnie się tutaj zachowuje ;) Z kolei samemu analizować, w jakim kodowaniu to jest mi się nie chce, to tylko drobny projekt na uczelnię...

0

Z kodowaniami tak to już jest - ten sam plik będzie wyglądał różnie dla różnych kodowań.

Może olej znaki i przetwarzaj bajty?

0

Myślałem nad tym rozwiązaniem, ale domyślnie szyfrowanie miało się opierać właśnie na tablicach znaków. Nic nie stoi na przeszkodzie, żeby oprzeć je o bajty, ale to będę musiał jeszcze skonsultować ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1