Значення вартості Unicode, яке я можу використовувати?


14

Я розробляю формат файлу і хочу зробити це правильно. Оскільки це двійковий формат, найперший байт (або байти) файлу не повинен утворювати дійсних текстових символів (як у заголовку 1 файлу PNG ). Це дозволяє інструментам, які не розпізнають формат, все одно бачити, що це не текстовий файл, переглядаючи перші кілька байтів.

Будь-яка кодова точка вище 0x7Fнедійсна US-ASCII, тому це просто. Але для Unicode - це зовсім інша історія. Окрім дійсних символів Unicode, існують символи приватного користування , нехарактерні та дозорні , як я виявив у персональних запитаннях щодо Unicode з приватним користуванням, нехарактерними запитаннями та надісланими .

Що таке дозорна послідовність байтів, яку я можу використовувати на початку файлу, що призведе до недійсних US-ASCII, UTF-8, UTF-16LE та UTF-16BE?

  • Очевидно, перший байт не може мати значення нижче, 0x80оскільки це було б дійсним символом US-ASCII (управління), тому 0x00його не можна використовувати.
  • Крім того, оскільки символи приватного використання є дійсними символами Unicode, я також не можу використовувати ці точки коду.
  • Оскільки він повинен працювати як з мало-ендіанським, так і з великим-ендіанським UTF-16, такий нехарактерний характер , як 0xFFFEвін, також неможливий, оскільки його зворотний зв'язок 0xFEFFє дійсним символом Unicode.
  • Вищезгаданий вище FAQ пропонує не використовувати жодне нехарактерне значення, оскільки це все одно призведе до дійсної послідовності Unicode, тому щось подібне 0xFFFFтакож не відображається.

Якими будуть довірені дозорні значення, які мені залишаються використовувати?


1 ) Формат PNG має як перший байт значення, яке не є ASCII 0x89, а потім рядок PNG. Інструмент, який читає перші кілька байт PNG, може визначити, що це двійковий файл, оскільки він не може інтерпретувати 0x89. Файл GIF, з іншого боку, починається безпосередньо з дійсної та читабельної рядка ASCII, GIFа потім ще трьох дійсних символів ASCII. Для GIF інструмент може визначити, що це текстовий файл, що читається. Це неправильно, і ідея запускати файл із нетекстурною послідовністю байтів виникла з проектування файлових форматів Енді Макфаддена.


3
Since it is a binary format, the first bytes of the file should not form valid textual characters- Ви повинні подивитися на чарівний файл (/ usr / share / magic або / etc / magic у багатьох системах Unix), який показує, як ця програма визначає типи файлів. Файл PNG починається з \x89PNG\x0d\0a\x1a\x0a- відмітьте "PNG" там, це необроблена рядок. Послідовності \x89тощо можуть бути недрукованими байтами.

@MichaelT Так, оскільки PNG є двійковим форматом, перший байт не утворює дійсного текстового символу. Це я мав на увазі. Я не бачу вашої точки зору?
Daniel AA Pelsmaeker

7
Це був приклад. .Gif починається з GIF8. Файл SGI Movi починається з MOVI. Починається один стиль файлу zip-архіву, починається з ZZбільш популярного формату pkzip PK. Обмеження, що перший байт є невірним символом тексту, схоже, не відповідає тому, що знаходиться в дикій природі. Мені цікаво, чому це вимога.

3
Вам дійсно все одно, як поводяться інші програми, коли вони бачать невідомий файл? Для мене послідовність підписів (як файли PNG) набагато корисніша за послідовність дозорних - коли вміст надсилається за допомогою простого протоколу потоку, одержувач може негайно вирішити, як обробляти наступні байти. Послідовність Omani-sentinel розташована поруч із не послідовністю, коли кожен починає використовувати її для виявлення власного формату.
Кодизм

2
@Virtlink, мене особливо не хвилює, які байти ви використовуєте у своєму файловому форматі. Але ви зробили твердження, що "неправильно" використовувати символи ascii ... але я тут не бачив нічого, що б підтверджувало це твердження, і є багато емпіричного досвіду, який показує, що це насправді не має значення (тобто незліченна кількість файлів формати, які десятиліттями без проблем використовують символи ASCII)
GrandmasterB

Відповіді:


16

0xDC 0xDC

  • Очевидно недійсні UTF-8 та ASCII
  • Супугат супроводу в парному положенні у положенні провідника незалежно від витривалості у UTF-16. Він не отримує більше недійсного UTF-16 від цього.

Але абсолютно розумний ISO-8859-1 і, ймовірно, розумний у будь-якому іншому наборі символів, який використовує 8-бітове кодування.
parsifal

4
+1 ОП не просили ISO 8859-1, лише US-ASCII та UTF- *.
Росс Паттерсон

@RossPatterson - правда, але я підозрюю, що це головним чином тому, що ОП насправді не продумала проблему. Не маючи жодної статистики, щоб підкріпити мене, я готовий зробити ставку на те, що алгоритм "випадковий текст" є випадковим, що більше шансів надати перевагу ISO-8859-1, ніж UTF-16, просто тому, що існує величезна кількість 8-бітових текст у світі.
parsifal

3
@parsifal Будь-який двійковий код дійсний ISO-8859-1, тому його не потрібно розглядати просто тому, що неможливо зробити недійсним ISO-8859-1.
Есаїлія

1
@parsifal вірно, і якщо це була вимога, яку ви можете просто використати 0x00або будь-що інше, але оп не хотів цього.
Есаїлія

5
  • У UTF-8 байти C0, C1 та F5 - FF є незаконними. Перший байт повинен бути або ASCII, або байт у діапазоні C2-F4, будь-який інший початковий байт недійсний UTF-8.

  • У UTF-16 файл, як правило, починається з позначки порядку байтів (U + FEFF), інакше програми повинні вгадувати в порядку байтів. Кодові точки в діапазоні D800-DBFF є провідними байтами для сурогатної пари, а DC00-DFFF є проміжними байтами для сурогатної пари.

Таким чином, я б використав байт комбо F5DC. Ці два значення:

  • Не ASCII
  • Недійсний UTF-8
  • Або інтерпретується як трейд-байт UTF-16 у сурогатній парі (не законний), або кодова точка U + F5DC, яка є приватним символом використання, але лише додатками, які вперто намагаються інтерпретувати це як UTF-16 навіть без BOM .

Якщо вам потрібно більше варіантів, F5DDчерез , щоб F5DFвсі вони мають ті ж 3 властивості, як і у F6DC- F6DF, F7DC- F7DFі F8DC- F8DF, в цілому 16 різних байт комбо , щоб вибрати з.


Отже, згідно з пропозицією Ісаїлії використовувати U + DCDC, чи 0xDCбуло б дійсним UTF-8?
Daniel AA Pelsmaeker

2
@Virtlink 0xDC- вихідний байт UTF-8 для 2-байтної послідовності. Після цього повинен бути 10xxxxxxбайт продовження, щоб він був дійсним. 0xDCне є дійсним байтом продовження, тому 0xDC 0xDCне є дійсним UTF-8.
Есаїлія

@Virtlink: Ні, оскільки другий байт недійсний, він повинен бути в діапазоні 80- BF.
Martijn Pieters

2

Якщо ви намагаєтесь використовувати символ, який не можна роздрукувати, щоб вказати "не текст", вам буде важко перемогти 0x89:

  • Це поза діапазоном США-ASCII
  • У ISO-8859-1 це символ, що не друкується ("ХАРАКТЕРНА ТАБУЛЯЦІЯ З ОБРАЗОМ"). Так само і з Shift-JIS, який, на мою думку, все ще використовується. Однак інші 8-бітні кодування можуть вважати це дійсним символом.
  • У UTF-8 це недійсний перший байт для багатобайтової послідовності (верхні біти - 10, які зарезервовані для символів 2..N багатобайтової послідовності)

Як правило, коли ви формуєте магічні числа, "нетекстовий" - це другорядний момент. Мені доведеться шукати посилання, але один із стандартних графічних форматів (я думаю, TIFF) має щось схоже на шість різних фрагментів корисної інформації з його магічного числа.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.