Tag: converter

O co chodzi z latin1 i dlaczego działają w nim polskie znaki

latin1

Kodowanie ISO/IEC 8859-1 znane pod nazwami takimi jak zachodnioeuropejskie Latin-1 latin1 oraz ISO-8859-1, obojętnie jakiej nazwy użyjemy zawsze chodzi o to samo kodowanie. Ważna zasada, której się trzymajmy i którą wyjaśnię:

kodowanie latin1, ISO-8859-1 nie obsługuje polskich znaków ani nie istnieją one w tym kodowaniu

Polskie znaki jednak jakimś cudem działają, bardzo prosto da się to wyjaśnić: w tym kodowaniu nie ma polskich znaków, ani polskie znaki w nim nie istnieją. Ale jednak jakimś cudem działają… Otóż działają dzięki temu, że wszystkie kodowania z rodziny ISO-8859 są ze sobą zgodne Konwersja z CP-1250 na utf8 – Convert from CP-1250 to utf8.

Bardziej łopatologicznie, mamy stronę w kodowaniu ISO-8859-2 (to kodowanie obsługuje polskie znaki) więc wysyłamy przykładowo ciąg polskich znaków: ą,ć,ę,ł,ń,ó,ś,ź,ż,Ą,Ć,Ę,Ł,Ń,Ó,Ś,Ź,Ż lecz należy pamiętać iż nasz serwer mysql, baza danych oraz tabele jak i kolumny korzystają z kodowania latin1 (najczęściej z porównaniem znaków ustawionym na latin1_swedish_ci) więc powyższy ciąg zostanie zastąpiony krzakami ±,æ,ê,³,ñ,ó,¶,¼,¿,¡,Æ,Ê,£,Ñ,Ó,¦,¬,¯, i niestety po zapisie w bazie mamy krzaczki zamiast polskich znaków Konwersja z ISO-8859-1 na UTF-8 – Convert from ISO-8859-1 to UTF-8.

Lecz należy pamiętać, iż jest o wiele więcej znaków specjalnych, które są zamieniane na krzaczki nie mające nic wspólnego z oryginalnymi znakami.

Ten problem z kodowaniem dotyczy głównie baz mysql, jeśli nie tylko baz. Dlatego zrobiłem konwerter, który przywraca polskie znaki w kopiach baz danych zapisanych za pomocą phpMyAdmin (ponieważ phpMyAdmin zapisuje wszystkie kopie baz danych w kodowaniu UTF-8).

Jeśli kopia została wykonana za pomocą phpMyAdmin lub innego skryptu który koduje kopie baz w UTF-8, a sama baza danych pracuje w kodowaniu latin1 to zrobiłem konwerter Konwersja z latin1 na latin2 – Convert from latin1 to latin2, zamienia krzaczki z takiej kopii na polskie znaki w kodowaniu ISO-8859-2 (przy imporcie takiego pliku należy wybrać z listy latin2) oraz Konwersja z latin1 na utf8 – Convert from latin1 to utf8 który zamienia znów krzaczki w kopii na polskie znaki, tym razem w kodowaniu UTF-8 (przy imporcie wybieramy utf8 z listy).

Należy także pamiętać by w pliku z kopią bazy danych po konwersji z latin1 na latin2 w pliku z kopią zmodyfikować linijki:

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

na:

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES latin2 */;

Przy konwersji z latin1 na utf8 ten zabieg jest zbędny! Przy imporcie za pomocą linii komend także należy podać właściwe kodowanie.

W skrócie, jeśli polskim znakom w twojej kopi bazy odpowiadają krzaczki takie jak w tabelce niżej, to po eksporcie, ten konwerter naprawi twoja bazę. (jeśli miałeś kodowanie latin1) Konwersja z Windows-1250 na ISO-8859-2 – Convert from Windows-1250 to ISO-8859-2

HEXlatin2latin1
b1ą±
e6ćæ
eaęê
b3ł³
f1ńñ
f3óó
b6ś
bcź¼
bfż¿
a1Ą¡
c6ĆÆ
caĘÊ
a3Ł£
d1ŃÑ
d3ÓÓ
a6Ś¦
acŹ¬
afŻ¯

Oraz wywołanie zapytania:

SHOW VARIABLES LIKE 'character_set%';

powoduje wyświetlenie wyników podobnych do tych:

character set clientlatin1
character_set_connectionlatin1
character set databaselatin1
character_set_resultslatin1
character_set_serverlatin1
character_set_systemlatin1

jak i tego:

SHOW VARIABLES LIKE 'collation%';

do tych:

collation_connectionlatin1_swedish_ci
collation_databaselatin1_swedish_ci
collation_serverlatin1_swedish_ci

Oznacza to że w bazie masz kraczki, zamiast właściwych znaków. Należy także pamiętać o ustawieniu właściwego kodowania dla tabel, bazy jak i połączenia z mysql, opisałem to ISO-8859-1 latin1 ISO-8859-2 latin2 Windows-1250 cp-1250 UTF-8 utf8 i jest tam zawarte jak wgrać bazę by przyjęła kodowanie ustawione wcześniej jak i ustawienie kodowania dla połączenia z mysql.

Pragnę przypomnieć, że konwerter kodowania obsługuje całe 167 znaków z kodowania iso-8859-2 zapisane w krzakach z latin1 a nie tylko polskie znaki!

ISO-8859-1 latin1 ISO-8859-2 latin2 Windows-1250 cp-1250 UTF-8 utf8

ISO-8859-1 latin1 ISO-8859-2 latin2 Windows-1250 cp-1250 UTF-8 utf8

Głęwiem wstępu intotrintorestycznego do convertera dodałem nowe tablice dla kodowania latin1, w którym polskie znaki są zapisane jako krzaczki, krzaki. Otóż konwersja z kodowania ISO-8859-1, w którym nie istnieją polskie znaki, jest jedynie dla kopii baz danych w pliku wykonanych za pomocą phpMyAdmin czyli plików kopii zapisanych w kodowaniu UTF-8 (w tym kodowaniu phpMyAdmin eksportuje bazę danych do pliku). Poprzednie tablice obsługiwały tylko i wyłącznie polskie znaki, co niestety nie służyło polepszeniu stosunków z innymi narodowe znaki i osobami wykorzystujące te znaki diakrytyczne. Teraz tablice obsługują wszelkie znaki (wszelkie języki) które są w kodowaniu ISO-8859-2 Konwersja z latin1 na utf8 – Convert from latin1 to utf8.

  • Polski
  • Bośniacki
  • Chorwacki
  • Czeski
  • Węgierski
  • Serbski (w transkrypcji łacińskiej)
  • Serbsko-Chorwacki
  • Słowacki
  • Słoweński
  • Górnołużycki
  • Dolnołużycki
  • Angielski
  • Niemiecki
  • sporną kwestią jest język Fiński

Dla porównania, poprzednie tablice do konwersji na utf-8 zawierająca tylko 18 polskich znaków natomiast aktualne zawierają wszystkie znaki dla wszystkich języków i znaków specjalnych zawierająca wszystkie istniejące znaki w tym kodowaniu – 167 znaki.
Teraz po konwersji z latin1 bez problemu można konwertować – wszelkie znaki będą działać!

Kodowanie znaków

Kodowanie znaków
Polega na zapisie znaków w celu ich późniejszego odczytania w tym samym kodowaniu. W skrócie, zapisujemy dane w jednym kodowaniu i następnie by je poprawnie odczytać należy odczytać w tym samym kodowaniu a którym je zapisaliśmy. Zapisujemy w kodowaniu utf-8 i odczytujemy w utf-8. Jeśli odczytamy w innym to pojawia się nam krzaki zamiast oczekiwanych znaków. Różne kodowania obsługują różne znaki, najczęściej nieobsługiwane znaki w danym kodowaniu są zamieniane na znaki zapytania.

Pragnę przypomnieć: w kodowaniu latin1 polskie znaki są zapisane jako krzaki, i po konwersji z kodowania latin1 do ISO-8859-2 lub UTF-8 na stronie Konwersja z latin1 na latin2 – Convert from latin1 to latin2, krzaki zapisane w bazie przemieniają się w polskie znaki (znaki diakrytyczne, narodowościowe, narodowe). Polskie znaki są zapisywane jako krzaki najczęściej na serwerach na których jest domyślna konfiguracja serwera mysql, wyglądająca następująco, konfigurację poznamy wykonując kolejno zapytania:
kodowanie mysql

SHOW VARIABLES LIKE 'character_set%';

domyślna konfiguracja serwera mysql:

character set clientlatin1
character_set_connectionlatin1
character set databaselatin1
character_set_resultslatin1
character_set_serverlatin1
character_set_systemlatin1

porównywanie mysql

domyślne porównania serwera mysql

SHOW VARIABLES LIKE 'collation%';
collation_connectionlatin1_swedish_ci
collation_databaselatin1_swedish_ci
collation_serverlatin1_swedish_ci

Jeśli twoje ustawienia są takie jak powyżej, a działają Ci polskie znaki to oznacza, że nie masz polskich znaków a jedynie krzaczki w bazie danych w kodowaniu latin1 Konwersja z ISO-8859-2 na UTF-8 – Convert from ISO-8859-2 to UTF-8 tak naprawdę mamy mnóstwo krzaków zamiast polskich znaków…

Naprawa krzaczków polskich znaków to zrobienie backupu bazy i konwersja za pomocą konwerter kodowań z latin1 na dowolne inne, należy pamiętać,że przy wgrywaniu takiej przekonwertowanej kopii należy wybrać to samo kodowanie na które przekonwertowaliśmy naszą kopię bazy, należy pamiętać o wybraniu zgodności mysql40 Konwersja z UTF-8 na ISO-8859-2 – Convert from UTF-8 to ISO-8859-2, oraz przed wgraniem należy ustawić kodowanie dla bazy by wgrywane tabele ze zgodnością mysql40 przyjęły właściwe kodowanie (ustawiamy także to samo na które przekonwertowaliśmy bazę) za pomocą zapytania:

ALTER DATABASE nazwa_bazy DEFAULT CHARACTER SET nazwa_kodowania COLLATE porównanie_znaków_dla kodowania;

dla kodowania latin2 będzie to wyglądać tak:

ALTER DATABASE nazwa_bazy DEFAULT CHARACTER SET latin2 COLLATE latin2_general_ci;

dla kodowania utf8:

ALTER DATABASE nazwa_bazy DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Teraz po takim ustawieniu, wszelkie tabele wgrywane ze zgodnością z mysql40 przyjmą kodowanie jakie ustawiliśmy dla bazy danych. Następnie aby je poprawnie odczytać ustawiamy odpowiednie kodowanie za pomocą SET NAMES oraz aby poprawnie wyświetlić ustawiamy odpowiednią definicję kodowania w pliku HTML. Od tej pory w naszej bazie danych istnieją polskie znaki.

Kolejna informacja: latin1 to to samo kodowanie co ISO-8859-1 tylko, że pod inną nazwą. Tak samo jest z latin2, jest to to samo kodowanie co ISO-8859-2. Są to odmienne nazwy, można ich używać zamiennie, zależy także od zastosowania, uproszczone nazwy najczęściej są wykorzystywane w bazach SQL MYSQL

SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'

a ich dłuższe odpowiedniki na stronach w definicji kodowej HTML. Przykładowo dla treści typu text/html oraz kodowania utf-8

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

SET NAMES ‘charset_name’ COLLATE ‘collation_name’

Otóż w każdym skrypcie w jakim łączymy się z mysql powinniśmy tuż po połączeniu z bazą danych ustawić kodowanie i porównanie z jakiego będziemy korzystać. To jest tak samo jak definicja kodowania w dokumencie HTML / XHTML, jeśli nie ustawimy to zdajemy się na wartości serwera, co często jest opłakane w skutkach na przykład będziemy próbować zapisać tekst zakodowany w utf-8 do bazy w kodowaniu latin2 Konwersja z latin2 na utf8 – Convert from latin2 to utf8, życzę powodzenia…

SET NAMES 'charset_name'

Otóż SET NAMES ustawia 3 parametry na raz z których będzie korzystać nasze połączenie z bazą, w miejsce charset_name wstawiamy nazwę kodowania w formacie odpowiednim dla MYSQL (kiedyś może zrobię listę), a te trzy parametry to:

character_set_client
character_set_results
character_set_connection
character_set_client
Ustawia kodowanie dla klienta
character_set_results
Ustawia kodowanie dla wyników zapytań
character_set_connection
Ustawia kodowanie dla połączenia

Konwersja z utf8 na latin2 – Convert from utf8 to latin2
I te 3 ustawienia konfigurujemy za pomocą jednego SET NAMES. Dochodzi jeszcze porównywanie połączeń (collate, collation) które ustawiamy poprzez dodanie drugiego parametru do SET NAMES, wygląda to tak:

SET NAMES 'charset_name' COLLATE 'collation_name'

Porównywanie to w dużym skrócie sortowanie wyników wedle wybranego kodowania (na przykład przy wybraniu utf8_polish_ci wyniki będą sortowane zgodnei z polskim alfabetem – alfabetycznie). Za charset_name wstawiamy nazwę kodowania a za collation_name wstawiamy nazwę porównywania. Parametr COLLATE ustawia 2 parametry na raz:

collation_connection
collation_database

Konwersja z Windows-1250 na UTF-8 – Convert from Windows-1250 to UTF-8

collation_connection
porównywanie znaków dla połączenia
collation_database
porównywanie znaków dla bazy danych

Informacje o dawno zapomnianym koderku https://tosiek.pl/koderek/, oczywiście to wszystko dotyczy konwerter.