Un valore sentinella Unicode che posso usare?


14

Sto progettando un formato di file e voglio farlo nel modo giusto. Poiché si tratta di un formato binario, il primo byte (o byte) del file non dovrebbe formare caratteri testuali validi (proprio come nell'intestazione del file PNG 1 ). Ciò consente agli strumenti che non riconoscono il formato di vedere ancora che non è un file di testo guardando i primi byte.

Qualsiasi punto di codice sopra riportato 0x7Fnon è valido US-ASCII, quindi è facile. Ma per Unicode è una storia completamente diversa. Oltre ai caratteri Unicode validi ci sono personaggi , caratteri non sentiti e sentinelle per uso privato , come ho trovato nelle Domande frequenti su personaggi , personaggi non sentiti e sentinelle per uso privato Unicode .

Quale sarebbe una sequenza sentinella di byte che posso usare all'inizio del file che comporterebbe US-ASCII, UTF-8, UTF-16LE e UTF-16BE non validi?

  • Ovviamente il primo byte non può avere un valore inferiore in 0x80quanto sarebbe un carattere US-ASCII (controllo) valido, quindi 0x00non può essere utilizzato.
  • Inoltre, poiché i caratteri per uso privato sono caratteri Unicode validi, non posso nemmeno usare quei punti di codice.
  • Dal momento che deve funzionare con UTF-16 sia little-endian che big-endian, un non carattere come quello 0xFFFEnon è possibile in quanto il suo contrario 0xFEFFè un carattere Unicode valido.
  • Le FAQ sopra menzionate suggeriscono di non utilizzare nessuno dei non caratteri in quanto ciò comporterebbe comunque una sequenza Unicode valida, quindi qualcosa del genere 0xFFFFè anche fuori dall'immagine.

Quali sarebbero i valori sentinella a prova di futuro che mi restano da usare?


1 ) Il formato PNG ha come primo byte il 0x89valore non ASCII , seguito dalla stringa PNG. Uno strumento che legge i primi byte di un PNG può determinare che si tratta di un file binario poiché non può essere interpretato 0x89. Un file GIF, d'altra parte, inizia direttamente con la stringa ASCII valida e leggibile GIFseguita da altri tre caratteri ASCII validi. Per GIF uno strumento potrebbe determinare che si tratta di un file di testo leggibile. Questo è sbagliato e l'idea di avviare il file con una sequenza di byte non testuali è nata da Designing File Formats di Andy McFadden.


3
Since it is a binary format, the first bytes of the file should not form valid textual characters- Dovresti guardare il file magico (/ usr / share / magic o / etc / magic su molti sistemi unix) che mostra come questa applicazione identifica i tipi di file. Un file PNG inizia con \x89PNG\x0d\0a\x1a\x0a- nota il "PNG" lì dentro, che è una stringa non elaborata . Le sequenze \x89e simili sono byte non stampabili.

@MichaelT Sì, poiché PNG è un formato binario, il primo byte non forma un carattere testuale valido. Ecco cosa intendevo. Non riesco a capire il tuo punto di vista?
Daniel AA Pelsmaeker,

7
Questo è stato un esempio. Un .gif inizia con GIF8. Un file movi SGI inizia con MOVI. Uno stile di file di archivio zip inizia con ZZ, inizia il formato pkzip più popolare PK. Il vincolo che il primo byte sia un carattere di testo non valido non sembra corrispondere a ciò che si trova in natura. Sono curioso di sapere perché questo è un requisito.

3
Ti interessa davvero come si comportano gli altri programmi quando vedono un file sconosciuto? Per me, una sequenza di firme (come i file PNG) è molto più utile di una sequenza sentinella - quando il contenuto viene inviato attraverso un semplice protocollo di flusso, il destinatario può decidere immediatamente come gestire i seguenti byte. Una sequenza Omani-sentinella si trova accanto a nessuna sequenza quando tutti iniziano a usarla per identificare il proprio formato.
Codismo

2
@Virtlink, non mi interessa particolarmente quali byte usi nel tuo formato di file. Ma hai affermato che è "sbagliato" usare i caratteri ASCII ... eppure qui non ho visto nulla che supporti tale affermazione, e c'è molta esperienza empirica che dimostra che davvero non importa (vale a dire, il numero infinito di file formati che usano i caratteri ASCII senza problemi da decenni)
GrandmasterB

Risposte:


16

0xDC 0xDC

  • Ovviamente UTF-8 e ASCII non validi
  • Surrogato di pista non accoppiato in posizione di vantaggio indipendentemente dall'endianità in UTF-16. Non ottiene più UTF-16 non valido di così.

Ma ISO-8859-1 perfettamente ragionevole, e probabilmente ragionevole in qualsiasi altro set di caratteri che utilizza una codifica a 8 bit.
parsifal

4
+1 OP non ha richiesto ISO 8859-1, solo US-ASCII e UTF- *.
Ross Patterson,

@RossPatterson - vero, ma sospetto che ciò sia dovuto principalmente al fatto che l'OP non ha davvero riflettuto sul problema. Senza alcuna statistica per supportarmi, sono disposto a scommettere che un algoritmo casuale "è questo testo" è più probabile che dia la preferenza a ISO-8859-1 rispetto a UTF-16, semplicemente perché c'è un'enorme quantità di 8 bit testo nel mondo.
parsifal

3
@parsifal Qualsiasi binario è valido ISO-8859-1, quindi non deve essere considerato semplicemente perché è impossibile rendere ISO-8859-1 non valido.
Esailija,

1
@parsifal true e se quello era il requisito che potevi semplicemente usare 0x00o altro, ma op non lo voleva.
Esailija,

5
  • In UTF-8, i byte C0, C1 e F5 - FF sono illegali. Il primo byte deve essere ASCII o un byte nell'intervallo C2-F4, qualsiasi altro byte iniziale non è valido UTF-8.

  • In UTF-16, il file inizia normalmente con il Byte Order Mark (U + FEFF), altrimenti le applicazioni devono indovinare nell'ordine dei byte. I punti di codice nell'intervallo D800-DBFF sono byte iniziali per una coppia surrogata e DC00-DFFF sono i byte finali per una coppia surrogata.

Quindi, userei la combinazione di byte F5DC. Questi due valori sono:

  • Non ASCII
  • UTF-8 non valido
  • O interpretato come un byte finale UTF-16 in una coppia surrogata (non legale), o il punto di codice U + F5DC, che è un carattere di uso privato, ma solo da applicazioni che cercano ostinatamente di interpretarlo come UTF-16 anche senza una distinta base .

Se hai bisogno di più opzioni, F5DDfino a F5DFtutte hanno le stesse 3 proprietà, come do F6DC- F6DF, F7DC- F7DFe F8DC- F8DF, per un totale di 16 diverse combinazioni di byte tra cui scegliere.


Quindi, secondo il suggerimento di Esailija di usare U + DCDC, 0xDCsarebbe valido UTF-8?
Daniel AA Pelsmaeker,

2
@Virtlink 0xDCè un byte iniziale UTF-8 per una sequenza di 2 byte. Deve essere seguito da un 10xxxxxxbyte di continuazione affinché sia ​​valido. 0xDCnon è un byte di continuazione valido, quindi 0xDC 0xDCnon è UTF-8 valido.
Esailija,

@Virtlink: No, poiché il secondo byte non è valido, dovrebbe essere compreso nell'intervallo 80- BF.
Martijn Pieters,

2

Se stai cercando di utilizzare un carattere non stampabile per indicare "non testo", sarà difficile battere 0x89:

  • È al di fuori dell'intervallo US-ASCII
  • In ISO-8859-1 è un carattere non stampabile ("TABOLAZIONE DEL PERSONAGGIO CON GIUSTIFICAZIONE"). Allo stesso modo con Shift-JIS, che credo sia ancora di uso comune. Altre codifiche a 8 bit possono tuttavia considerare questo come un carattere valido.
  • In UTF-8 è un primo byte non valido per una sequenza multi-byte (i bit superiori sono 10, che sono riservati per i caratteri 2..N di una sequenza multi-byte)

Generalmente, quando si formano numeri magici, "non testo" è un punto minore. Dovrò cercare il riferimento, ma uno dei formati grafici standard (TIFF, credo) ha qualcosa come sei diversi pezzi di informazioni utili dal suo numero magico.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.