Wartość wartownika Unicode, której mogę użyć?

14

Wybieram format pliku i chcę to zrobić poprawnie. Ponieważ jest to format binarny, pierwszy bajt (lub bajty) pliku nie powinien tworzyć prawidłowych znaków tekstowych (tak jak w nagłówku 1 pliku PNG ). Dzięki temu narzędzia, które nie rozpoznają formatu, mogą zobaczyć, że nie jest to plik tekstowy, patrząc na kilka pierwszych bajtów.

Każdy punkt kodowy powyżej 0x7Fjest nieprawidłowy US-ASCII, więc to proste. Ale dla Unicode to zupełnie inna historia. Oprócz prawidłowych znaków Unicode są też znaki prywatnego użytku , non - charar i sentinels , jak znalazłem w FAQ dla Unicode prywatnych znaków, non-charar i Sentinels .

Jaka byłaby sekwencja wartowników, których mogłabym użyć na początku pliku, co spowodowałoby nieprawidłowe US-ASCII, UTF-8, UTF-16LE i UTF-16BE?

  • Oczywiście pierwszy bajt nie może mieć wartości poniżej, 0x80ponieważ byłby to prawidłowy znak US-ASCII (kontrolny), więc 0x00nie można go użyć.
  • Ponadto, ponieważ znaki do użytku prywatnego są prawidłowymi znakami Unicode, nie mogę również używać tych znaków kodowych.
  • Ponieważ musi działać zarówno z UTF-16 little-endian, jak i big-endian, znak taki jak 0xFFFErównież nie jest możliwy, ponieważ jego odwrotność 0xFEFFjest poprawnym znakiem Unicode.
  • Wyżej wspomniane FAQ sugeruje, aby nie używać żadnych znaków innych niż znaki, ponieważ nadal skutkowałoby to prawidłową sekwencją Unicode, więc coś podobnego 0xFFFFrównież nie wchodzi w grę .

Jakich przyszłych wartości wartowniczych pozostawiłbym do wykorzystania?


1 ) Format PNG ma jako pierwszy bajt wartość inną niż ASCII 0x89, po której następuje łańcuch PNG. Narzędzie, które odczytuje kilka pierwszych bajtów PNG, może stwierdzić, że jest to plik binarny, ponieważ nie może interpretować 0x89. Z drugiej strony plik GIF zaczyna się bezpośrednio od prawidłowego i czytelnego ciągu ASCII, GIFpo którym następują trzy kolejne prawidłowe znaki ASCII. W przypadku GIF narzędzie może stwierdzić, że jest to czytelny plik tekstowy. To źle, a pomysł uruchomienia pliku z nieteksturalną sekwencją bajtów przyszedł od Designing File Formats autorstwa Andy'ego McFaddena.

Daniel AA Pelsmaeker
źródło
3
Since it is a binary format, the first bytes of the file should not form valid textual characters- Powinieneś spojrzeć na magiczny plik (/ usr / share / magic lub / etc / magic na wielu systemach uniksowych), który pokazuje, jak ta aplikacja identyfikuje typy plików. Plik PNG zaczyna się od \x89PNG\x0d\0a\x1a\x0a- zwróć uwagę na „PNG”, który jest nieprzetworzonym ciągiem. Sekwencje \x89i tym podobne są bajtami, których nie można wydrukować.
@MichaelT Tak, ponieważ PNG jest formatem binarnym, pierwszy bajt nie tworzy prawidłowego znaku tekstowego. O to mi chodziło. Nie rozumiem twojego punktu widzenia?
Daniel AA Pelsmaeker,
7
To był przykład. .Gif zaczyna się od GIF8. Plik movi SGI zaczyna się od MOVI. Rozpoczyna się jeden styl pliku archiwum zip ZZ, od bardziej popularnego formatu pkzip PK. Ograniczenie, że pierwszy bajt jest niepoprawnym znakiem tekstowym, wydaje się nie pasować do tego, co można znaleźć na wolności. Jestem ciekawy, dlaczego jest to wymóg.
3
Czy naprawdę obchodzi Cię zachowanie innych programów, gdy widzą nieznany plik? Dla mnie sekwencja podpisu (podobnie jak pliki PNG) jest znacznie bardziej użyteczna niż sekwencja wartownika - gdy treść jest wysyłana za pomocą prostego protokołu strumieniowego, odbiorca może natychmiast zdecydować, jak obsłużyć następujące bajty. Sekwencja omańsko-wartownicza znajduje się obok braku sekwencji, gdy wszyscy zaczną używać jej do identyfikowania własnego formatu.
Codism
2
@ Virtlink, nie obchodzi mnie szczególnie, jakie bajty używasz w swoim formacie pliku. Ale stwierdziłeś, że „niewłaściwe” jest używanie znaków ascii ... ale nie widziałem tutaj niczego, co by to potwierdzało, i jest wiele doświadczeń empirycznych, które pokazują, że to naprawdę nie ma znaczenia (tj. Niezliczona ilość plików formaty, które od dziesięcioleci używają znaków ASCII)
GrandmasterB

Odpowiedzi:

16

0xDC 0xDC

  • Oczywiście nieprawidłowy UTF-8 i ASCII
  • Niesparowany szlak zastępczy w pozycji wiodącej, niezależnie od endianizmu w UTF-16. Nie ma więcej nieprawidłowego UTF-16 niż to.
Esailija
źródło
Ale całkowicie rozsądna ISO-8859-1 i prawdopodobnie rozsądna w każdym innym zestawie znaków, który wykorzystuje kodowanie 8-bitowe.
parsifal
4
+1 OP nie prosiło o ISO 8859-1, tylko US-ASCII i UTF- *.
Ross Patterson
@RossPatterson - prawda, ale podejrzewam, że to głównie dlatego, że OP tak naprawdę nie przemyślał problemu. Bez żadnych statystyk, które by mnie poparły, jestem skłonny założyć się, że losowy algorytm „to ten tekst” częściej preferuje ISO-8859-1 niż UTF-16, po prostu dlatego, że istnieje ogromna ilość 8-bitów tekst na świecie.
parsifal
3
@parsifal Każdy plik binarny jest prawidłowy ISO-8859-1, więc nie trzeba go brać pod uwagę po prostu dlatego, że niemożliwe jest uczynienie nieprawidłowym ISO-8859-1.
Esailija
1
@parsifal to prawda, a jeśli był to wymóg, którego możesz po prostu użyć 0x00lub cokolwiek, ale operacja tego nie chciała.
Esailija
5
  • W UTF-8 bajty C0, C1 i F5 - FF są nielegalne. Pierwszy bajt musi być albo ASCII, albo bajtem z zakresu C2-F4, żaden inny bajt początkowy jest nieprawidłowy UTF-8.

  • W UTF-16 plik zwykle zaczyna się od znaku kolejności bajtów (U + FEFF), w przeciwnym razie aplikacje muszą odgadnąć kolejność bajtów. Punkty kodowe w zakresie D800-DBFF są bajtami wiodącymi dla pary zastępczej, a DC00-DFFF są bajtami końcowymi dla pary zastępczej.

Tak więc użyłbym kombinacji bajtów F5DC. Te dwie wartości to:

  • Nie ASCII
  • Niepoprawny UTF-8
  • Zinterpretowany jako końcowy bajt UTF-16 w parze zastępczej (niezgodny z prawem) lub punkt kodowy U + F5DC, który jest znakiem do użytku prywatnego, ale tylko przez aplikacje, które uparcie próbują interpretować to jako UTF-16 nawet bez BOM .

Jeśli potrzebujesz więcej opcji, F5DDaż po F5DFwszystkie mają te same właściwości 3, a nie F6DC- F6DF, F7DC- F7DFi F8DC- F8DF, w sumie 16 różnych combo bajtowych do wyboru.

Martijn Pieters
źródło
Tak więc, zgodnie z sugestią Esailii, aby użyć U + DCDC, 0xDCczy byłby ważny UTF-8?
Daniel AA Pelsmaeker,
2
@ Virtlink 0xDCjest wiodącym bajtem UTF-8 dla sekwencji 2-bajtowej. Po nim musi być 10xxxxxxbajt kontynuacji, aby był ważny. 0xDCnie jest poprawnym bajtem kontynuacji, więc 0xDC 0xDCnie jest poprawny UTF-8.
Esailija,
@ Virtlink: Nie, ponieważ drugi bajt jest nieprawidłowy, musiałby mieścić się w zakresie 80- BF.
Martijn Pieters
2

Jeśli próbujesz użyć znaku niedrukowalnego do oznaczenia „nie tekst”, trudno będzie pokonać 0x89:

  • Jest poza zakresem US-ASCII
  • W ISO-8859-1 jest to znak niedrukowalny („TABULACJA ZNAKÓW Z UZASADNIENIEM”). Podobnie jest z Shift-JIS, który moim zdaniem jest nadal w powszechnym użyciu. Inne kodowania 8-bitowe mogą jednak traktować to jako prawidłowy znak.
  • W UTF-8 jest to nieprawidłowy pierwszy bajt dla sekwencji wielobajtowej (górne bity to 10, które są zarezerwowane dla znaków 2..N sekwencji wielobajtowej)

Zasadniczo, kiedy tworzysz magiczne liczby, „nietekstowy” jest drobną kwestią. Będę musiał sprawdzić referencje, ale jeden ze standardowych formatów graficznych (chyba TIFF) zawiera coś w rodzaju sześciu różnych przydatnych informacji z magicznej liczby.

parsifal
źródło