Modified UTF-8 (MUTF-8) originated in the Java programming language. In Modified UTF-8, the null character (U+0000) uses the two-byte overlong encoding 11000000 10000000 (hexadecimal C0 80), instead of 00000000 (hexadecimal 00).[65] Modified UTF-8 strings never contain any actual null bytes but can contain all Unicode code points including U+0000,[66] which allows such strings (with a null byte appended) to be processed by traditional null-terminated string functions.
Jestem zdziwiony.
Poprawcie mnie, jeśli się mylę, ale jak rozumiem, taka jest historia znaku NUL:
- W dawnych czasach (C itp) wymyślono, że wygodnie będzie założyć, że każdy ciąg znaków ma się kończyć specjalnym znakiem oznaczającym koniec tegoż ciągu znaków. Na taki specjalny znak wybrano 0x00. OK, w porządku.
- Aha, a więc powstał nowy znak do alfabetu, nazywamy go znakiem NUL.
- A skoro mamy nowy znak w alfabecie, to musimy umieć przedstawić go w napisie! Ups, ale nie możemy tak zrobić, bo z definicji ten znak kończy napis.
- Wspaniałe rozwiązanie: nasz stary, dobry NUL przenosi się na pozycję 0xC080, natomiast na pozycję 0x00 wstawiamy nowego nulla, który przejmuje funkcję starego nulla, czyli kończy ciąg znaków.
Aż się prosi, żeby dopisać ciąg dalszy tej historii:
- Aha, a więc powstał nowy znak do alfabetu, nazwijmy go znakiem MNUL (Modified NUL).
- A skoro tak, to powinniśmy być w stanie przedstawić go w napisie, z analogicznych powodów jak te, dla których chcemy starego NULa umieć przedstawić w napisie. Jednak nie możemy tego uczynić, bo postanowiliśmy, że MNUL zawsze kończy napis.
- Wspaniałem rozwiązanie: nasz nowy stary MNUL przenosi się na pozycję [tu wstaw dowolną dostępną pozycję], zaś na pozycję 0x00 wstawiamy jeszcze jednego nulla, który przejmuje funkcję obu starych nulli, czyli kończy ciąg znaków. Tak utworzone kodowanie znaków nazywamy 2MUTF-8 (Doubly Modified UTF-8).
- Aha, a więc powstał nowy znak do alfabetu, nazwijmy go znakiem 2MNUL (Doubly Modified NUL).
- A skoro mamy nowy znak w alfabecie.... i tak dalej, i tak dalej.
Przecież tak można w nieskończoność, to nie ma sensu.
Przyznaję się do słabości. Krytykuję, a nie mam lepszego pomysłu. Są przecież standardy, które nie kończą każdego napisu nulem w żadnej z jego inkarnacji, np. C# nie kończy stringów NULem i stringi mogą NULe przechowywać. Nie wiem, ale ślepo strzelam, że w takim razie każdy string musi przechowywać swoją długość? Ale w takim wypadku zachodzi konieczność przenoszenia napisów między różnymi standardami, na przykład przydałoby się być w stanie przechować napis C#-owy w napisie zakończonym nulem i to tak, by móc później odtworzyć oryginalny napis z powrotem do C#.
Unicode wprowadził znak U+2400 (␀). Z początku myślałem, że to jest prawidłowe rozwiązanie problemu: przerzucamy U+0000 na U+2400 i z powrotem. Ale przecież tak nie może być, bo to wprowadza niejednoznaczność. Co na przykład zrobić z takim napisem: W języku C każdy string jest zakończony znakiem ␀
?