Ein Unicode-Sentinel-Wert, den ich verwenden kann?

14

Ich entwerfe ein Dateiformat und möchte es richtig machen. Da es sich um ein Binärformat handelt, sollte das erste Byte (oder die ersten Bytes) der Datei keine gültigen Textzeichen bilden (genau wie im PNG-Dateikopf 1 ). Auf diese Weise können Tools, die das Format nicht erkennen, anhand der ersten Bytes erkennen, dass es sich nicht um eine Textdatei handelt.

Jeder obige Codepunkt 0x7Fist ungültig (US-ASCII), das ist also einfach. Aber für Unicode ist das eine ganz andere Geschichte. Neben gültigen Unicode - Zeichen gibt es Privatnutzungs Zeichen , noncharacters und Sentinels , wie ich in den gefundenen Unicode Privat-Use Charaktere, Noncharacters & Sentinels FAQ .

Was wäre eine Sentinel-Folge von Bytes, die ich am Anfang der Datei verwenden könnte und die zu ungültigem US-ASCII, UTF-8, UTF-16LE und UTF-16BE führen würde?

  • Offensichtlich kann das erste Byte keinen niedrigeren Wert haben 0x80, da dies ein gültiges US-ASCII-Zeichen (Steuerzeichen) wäre und daher 0x00nicht verwendet werden kann.
  • Da Zeichen für den privaten Gebrauch gültige Unicode-Zeichen sind, kann ich diese Codepunkte auch nicht verwenden.
  • Da es sowohl mit Little- Endian- als 0xFFFEauch mit Big-Endian-UTF-16 funktionieren muss , ist ein Nicht-Zeichen, wie es auch nicht möglich ist, da sein Gegenteil 0xFEFFein gültiges Unicode-Zeichen ist.
  • In den oben genannten häufig gestellten Fragen wird empfohlen , keine der Sonderzeichen zu verwenden, da dies immer noch zu einer gültigen Unicode-Sequenz führen würde 0xFFFF.

Welche zukunftssicheren Sentinel-Werte stehen mir noch zur Verfügung?


1 ) Das PNG-Format hat als erstes Byte den Nicht-ASCII- 0x89Wert, gefolgt von der Zeichenfolge PNG. Ein Tool, das die ersten paar Bytes eines PNG liest, stellt möglicherweise fest, dass es sich um eine Binärdatei handelt, da es diese nicht interpretieren kann 0x89. Eine GIF-Datei beginnt dagegen direkt mit der gültigen und lesbaren ASCII-Zeichenfolge, GIFgefolgt von drei weiteren gültigen ASCII-Zeichen. Für GIF kann ein Tool bestimmen, dass es sich um eine lesbare Textdatei handelt. Dies ist falsch und die Idee, die Datei mit einer nicht-texturalen Byte-Sequenz zu starten, stammt aus Designing File Formats von Andy McFadden.

Daniel AA Pelsmaeker
quelle
3
Since it is a binary format, the first bytes of the file should not form valid textual characters- Sie sollten sich die Magic-Datei ansehen (/ usr / share / magic oder / etc / magic auf vielen Unix-Systemen), die zeigt, wie diese Anwendung Dateitypen identifiziert. Eine PNG-Datei beginnt mit \x89PNG\x0d\0a\x1a\x0a- beachten Sie, dass "PNG" eine rohe Zeichenfolge ist. Die Sequenzen \x89und dergleichen sind nicht druckbare Bytes.
@MichaelT Ja, da PNG ein Binärformat ist, bildet das erste Byte kein gültiges Textzeichen. Das ist es was ich meinte. Ich verstehe deinen Standpunkt nicht?
Daniel AA Pelsmaeker
7
Das war ein Beispiel. Ein .gif beginnt mit GIF8. Eine SGI-Movi-Datei beginnt mit MOVI. Eine Art von Zip-Archivdateien beginnt mit ZZ, das populärere pkzip-Format beginnt mit PK. Die Einschränkung, dass das erste Byte ein ungültiges Textzeichen ist, scheint nicht mit dem übereinzustimmen, was in freier Wildbahn gefunden wird. Ich bin gespannt, warum dies eine Voraussetzung ist.
3
Interessiert es Sie wirklich, wie sich andere Programme verhalten, wenn sie eine unbekannte Datei sehen? Für mich ist eine Signatursequenz (wie PNG-Dateien) viel nützlicher als eine Sentinel-Sequenz - wenn der Inhalt über ein einfaches Stream-Protokoll gesendet wird, kann der Empfänger sofort entscheiden, wie mit den folgenden Bytes umgegangen werden soll. Eine Omani-Sentinel-Sequenz ist so gut wie keine Sequenz, sobald jeder damit beginnt, sein eigenes Format zu identifizieren.
Codism
2
@Virtlink, es ist mir egal, welche Bytes Sie in Ihrem Dateiformat verwenden. Sie haben jedoch die Behauptung aufgestellt, dass die Verwendung von ASCII-Zeichen „falsch“ ist. Dennoch habe ich hier nichts gesehen, was diese Behauptung stützt, und es gibt zahlreiche empirische Erfahrungen, die belegen, dass es wirklich egal ist (z. B. die unzähligen Dateien) Formate, die seit Jahrzehnten problemlos ASCII-Zeichen verwenden)
GrandmasterB

Antworten:

16

0xDC 0xDC

  • Offensichtlich ungültiges UTF-8 und ASCII
  • Ungepaarter Trail-Ersatz in führender Position, unabhängig von der Endianess in UTF-16. Es wird nicht mehr ungültiges UTF-16 als das erhalten.
Esailija
quelle
Aber durchaus vernünftig ISO-8859-1 und wahrscheinlich in jedem anderen Zeichensatz, der eine 8-Bit-Codierung verwendet.
Parsifal
4
+1 OP hat nicht nach ISO 8859-1 gefragt, nur nach US-ASCII und UTF- *.
Ross Patterson
@ RossPatterson - stimmt, aber ich vermute, das liegt hauptsächlich daran, dass das OP das Problem nicht wirklich durchdacht hat. Ohne Statistiken, die mich stützen, bin ich bereit zu wetten, dass ein zufälliger "Ist dieser Text" -Algorithmus eher ISO-8859-1 als UTF-16 bevorzugt, einfach weil es eine enorme Menge von 8-Bit gibt Text in der Welt.
Parsifal
3
@parsifal Jede Binärdatei ist gültig nach ISO-8859-1. Sie muss also nicht einfach berücksichtigt werden, da es unmöglich ist, eine ungültige ISO-8859-1 zu erstellen.
Esailija
1
@parsifal true und wenn das die Voraussetzung wäre, könntest du es einfach benutzen 0x00oder was auch immer, aber op wollte das nicht.
Esailija
5
  • In UTF-8 sind die Bytes C0, C1 und F5 - FF unzulässig. Das erste Byte muss entweder ASCII oder ein Byte im Bereich C2-F4 sein, jedes andere Startbyte ist ungültig UTF-8.

  • In UTF-16 beginnt die Datei normalerweise mit dem Byte Order Mark (U + FEFF), ansonsten müssen die Anwendungen die Byte-Reihenfolge erraten. Codepunkte im Bereich D800-DBFF sind führende Bytes für ein Ersatzpaar, und DC00-DFFF sind die nachfolgenden Bytes für ein Ersatzpaar.

Daher würde ich die Byte-Kombination verwenden F5DC. Diese beiden Werte sind:

  • Nicht ASCII
  • Nicht gültig für UTF-8
  • Entweder als UTF-16-Trailing-Byte in einem Ersatzpaar (nicht legal) interpretiert oder als Codepoint U + F5DC, ein Zeichen für den privaten Gebrauch, aber nur von Anwendungen, die hartnäckig versuchen, dies auch ohne Stückliste als UTF-16 zu interpretieren .

Wenn Sie mehr Optionen benötigen, haben F5DDbis F5DFalle dieselben 3 Eigenschaften wie F6DC- F6DF, F7DC- F7DFund F8DC- F8DF, sodass Sie aus insgesamt 16 verschiedenen Bytekombinationen auswählen können.

Martijn Pieters
quelle
Also, nach Esailijas Vorschlag , U + DCDC zu verwenden, 0xDCwäre UTF-8 gültig?
Daniel AA Pelsmaeker
2
@Virtlink 0xDCist ein UTF-8-Lead-Byte für eine 2-Byte-Sequenz. Es muss ein 10xxxxxxFortsetzungsbyte folgen , damit es gültig ist. 0xDCist kein gültiges Fortsetzungsbyte, daher 0xDC 0xDCist UTF-8 nicht gültig.
Esailija
@Virtlink: Nein, da das zweite Byte nicht gültig ist, müsste es im Bereich 80- liegen BF.
Martijn Pieters
2

Wenn Sie versuchen, ein nicht druckbares Zeichen zu verwenden, um "kein Text" anzugeben, ist es schwierig, 0x89 zu schlagen:

  • Es liegt außerhalb des US-ASCII-Bereichs
  • In ISO-8859-1 handelt es sich um ein nicht druckbares Zeichen ("CHARACTER TABULATION WITH JUSTIFICATION"). Ebenso mit Shift-JIS, von dem ich glaube, dass es immer noch gebräuchlich ist. Andere 8-Bit-Codierungen können dies jedoch als gültiges Zeichen behandeln.
  • In UTF-8 ist es ein ungültiges erstes Byte für eine Multibyte-Sequenz (die oberen Bits sind 10, die für die Zeichen 2..N einer Multibyte-Sequenz reserviert sind).

Wenn Sie magische Zahlen bilden, ist "Nicht-Text" im Allgemeinen ein untergeordneter Punkt. Ich muss die Referenz nachschlagen, aber eines der Standard-Grafikformate (TIFF, glaube ich) enthält ungefähr sechs verschiedene nützliche Informationen aus seiner magischen Zahl.

Parsifal
quelle