Konwersje z systemu UTF16 na UTF8 i odwrotnie, tworzenie punktów kodowych

0

Witam,
Muszę ogarnąć kilka rzeczy z teorii kodowania i nie mogę za nic w świecie zrozumieć pewnych rzeczy...

Przede wszystkim konwersji z systemu UTF16 na UTF8 i tworzenie punktów kodowych.

Powiedzmy, że dostałem plik w UTF16BE, który w zapisie hex wygląda tak:

FE FF 4D 9B 7A DB AB AA
I chcę go skonwertować na UTF8.

Mam tu przede wszystkim problem z konwersją ostatnich 4 bajtów tj. AB AA
Według mnie plik wyjściowy może wyglądać tak:

4D C2 9B C3 9B C2 AB C2 AA,
ale już według hexedytora (i konwerterów internetowych) plik wygląda tak:

4D C2 9B C3 9B EA AE AA.
Mógłby mi ktoś wyjaśnić jak konkretnie powinienem to robić?

dodanie znaczników <code> - fp

0
ABAAh = 1010101110101010b

    1010   101110   101010
1110xxxx 10xxxxxx 10xxxxxx

11101010 10101110 10101010
   EA       AE       AA
0

AB AA rozpisujesz binarnie:
1010 1011 1010 1010
Teraz patrzysz na ilu bitach mieści się ciąg znaków AB AA (czyli gdzie jest ostatnia jedynka patrząc od lewej strony). Jak widać jest to 16 bitów. Następnie patrzysz ilu tzw. wagoników musisz użyć, aby zapisać ten ciąg.
7 bitów- 0xxxxxxx
11 bitów - 110xxxxx 10xxxxxx
16 bitów- 1110xxxx 10xxxxxx 10xxxxxx
21 bitów - 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Jak widzisz ciąg ABAA musisz zapisać w tym trzecim ciągu bitów, bo on pomieści co najmniej 16 bitów.
No więc uzupełniasz - w miejsce symboli x wstawiasz zapisany binarnie ciąg AB AA zaczynając od końca.
Uzyskujesz dzięki temu taki ciąg zerojedynkowy:
1110 1010 1010 1110 1010 1010
czyli szesnastkowo:
E A A E A A
Czyli to konwerter miał rację.

0

No to właśnie wiem, tylko skąd wiadomo, że mam wziąć akurat AB AA, a nie samo AB, a potem AA?

Bo od początku to robię tak:
Biorę pierwsze 8 bitów i patrzę, że jest to już zapis UTF16, więc nie konwertuję.
Potem biorę kolejne 8 bitów i patrzę, że już muszę konwertować i dopisuje wagoniki. Potem kolejne 8 i kolejne i tak do końca.

Mogę od razu patrzeć na 16 bitów zamiast 8, ale wtedy moja koncepcja się trochę sknoci.

0

Moim zdaniem to już na samym początku jest błąd.
Ja bym na Twoim miejscu robił to tak, że jak masz zapisane wszystko w ten sposób:
4D 9B 7A DB AB AA
To dzielisz to na "czwórki":
4D9B 7ADB ABAA
Teraz po kolei sobie te czwórki zapisujesz binarnie w rządku i patrzysz na to ilu wagoników trzeba użyć. Czyli:
4D9B - 0100 1101 1001 1011 - 15 bitów - 1110xxxx 10xxxxxx 10xxxxxx
11100100 10110110 10011011
1110|0100 1011|0110 1001|1011
E 4 B 6 9 B
Czyli 4D9B po konwersji wygląda tak: E4 B6 9B
A Twój przykład po całkowitej konwersji będzie wyglądał tak:
E4 B6 9B E7 AB 9B EA AE AA
Przynajmniej według konwertera z tej strony http://macchiato.com/unicode/convert.html
Spróbuj zrobić tak jak Ci pokazałem na innym przykładzie i zobacz czy wyniki są poprawne.

0

No tak, ale patrząc zawsze na "czwórki" czy zawsze na "dwójki" ograniczamy się tylko do trzech opcji - jeden wagonik, dwa lub trzy. A przecież może się zdarzyć(w teorii), że potrzebne będzie np pięć wagoników.

Ja w ogóle najpierw wziąłem sobie ciąg UTF8 EF BB BF 4D C2 9B 7A C3 9B EA AE AA i zamieniłem go na UTF16BE, a potem w celu sprawdzenia chciałem zrobić odwrotnie, ale już nie wiedziałem jak. Także na pewno tam gdzie nie ma wagoników, albo gdzie jest tylko jeden to jest poprawnie. Problem zaczyna się dopiero przy ich większej ilości.

Wg mnie to nigdzie nie ma dokładnie pokazane ile trzeba "brać" bitów przy konwersji, więc pewnie jest na to jakaś inna metoda, której właśnie nie mogę znaleźć ani odkryć.
Chodzi mi jeszcze po głowie opcja ze znalezieniem najpierw punktów kodowych, a potem dopiero ich konwersja na UTF8, ale tego też nie potrafię zrobić.

0

że potrzebne będzie np pięć wagoników.
Nie będzie. W pierwotnej wersji UTF-8 mogło być 6, ale kody powyżej 4 nigdy nie były obsadzone. Potem obcięto standard do czterech.

Mając bajty kodu UTF16BE, tak jak powiedziałeś
FE FF 4D 9B 7A DB AB AA
zawsze bierzemy dwójkami. A ponieważ to jest big-endian, to nie zamieniamy kolejności bajtów, czyli:
FEFF 4D9B 7ADB ABAA
i teraz dopiero patrzymy, ile wagoników potrzeba. do wszystkich tych znaków trzeba trzech.
żeby był jeden, to musiałbyś mieć wartość np. 0020, czyli mała liczba ale już po zebraniu bajtów w dwójki.

a co z kodami większymi od FFFF? trzeba najpierw UTF-16 przekonwertować na UCS-4, czyli rozwinąć surrogate pairs, i dopiero konwertować na UTF-8.

0

A jakim sposobem skonwertowałeś ciąg EF BB BF 4D C2 9B 7A C3 9B EA AE AA zapisany w UTF-8? Wydaje się to na pierwszy rzut oka raczej trudne do zrealizowania. Zrób tak jak napisał @Azarien, a zdasz. :) Kiedyś też pytałem na tym forum o konwersję utf-8 i utf-16 i polecono mi dwie strony:
https://en.wikipedia.org/wiki/UTF-8
https://en.wikipedia.org/wiki/UTF-16
Jakbyś miał czas to też możesz się z nimi zapoznać.

0

Albo ja jestem tępy, albo to wszystko jest jakieś dziwne...
Po pierwsze przykład z EF BB BF 4D C2 9B 7A C3 9B EA AE AA jest żywcem wyciągnięty z kolokwium.
Po drugie robiłem to tak, że najpierw rozpisałem wszystko binarnie, potem szukałem wagoników, potem je usuwałem i dostałem ciąg FE FF 4D 9B 7A DB AB AA( w trakcie pisania tego posta zorientowałem się już co było nie tak, nie był to DOKŁADNIE taki ciąg, usunąłem z niego zera, przez co nie mogłem wrócić do pierwotnej pozycji). Dokładny ciąg to FE FF 4D 00 9B 7A 00 DB 00 AB AA. Teraz już ok.

Po trzecie grupując bity w sposób podany przez @Azarien nigdy nie wyjdziemy poza FFFF(albo ja czegoś tu nie rozumiem, wg mnie to jest grupowanie czwórkami a nie dwójkami).

0

Po drugie robiłem to tak, że najpierw rozpisałem wszystko binarnie, potem szukałem wagoników, potem je usuwałem i dostałem ciąg

Robisz to w złej kolejności. Najpierw zbierasz bajty po dwa, a potem dobierasz wagoniki.

Po trzecie grupując bity w sposób podany przez @Azarien nigdy nie wyjdziemy poza FFFF

Poczytaj artykuły na wikipedii o UTF-16.
Znaki powyżej FFFF są w UTF-16 kodowane jako para znaków z przedziału D800 - DFFF (chyba). Przed konwersją do UTF-8 trzeba je przeliczyć na znak >FFFF.

0

Dobra, wydaje mi się, że wszystko zrozumiałem, dzięki za pomoc.
Idę uczyć się trudniejszych rzeczy :)

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