Nilai sentinel Unicode yang dapat saya gunakan?

14

Saya mendesain format file dan saya ingin melakukannya dengan benar. Karena ini adalah format biner, byte pertama (atau byte) dari file tidak boleh membentuk karakter tekstual yang valid (seperti pada header file PNG 1 ). Ini memungkinkan alat yang tidak mengenali format untuk tetap melihat bahwa itu bukan file teks dengan melihat beberapa byte pertama.

Setiap codepoint di atas 0x7Ftidak valid US-ASCII, jadi itu mudah. Tetapi bagi Unicode, ini adalah cerita yang sangat berbeda. Terlepas dari karakter Unicode yang valid ada karakter penggunaan pribadi , noncharacters dan sentinels , seperti yang saya temukan di FAQ Unicode Private-Use Characters, Noncharacters & Sentinels .

Apa yang akan menjadi urutan sentinel byte yang dapat saya gunakan pada awal file yang akan menghasilkan US-ASCII, UTF-8, UTF-16LE dan UTF-16BE yang tidak valid?

  • Jelas byte pertama tidak dapat memiliki nilai di bawah 0x80karena itu akan menjadi karakter US-ASCII (kontrol) yang valid, jadi 0x00tidak dapat digunakan.
  • Juga, karena karakter penggunaan pribadi adalah karakter Unicode yang valid, saya juga tidak dapat menggunakan codepoint tersebut.
  • Karena itu harus bekerja dengan baik UTF-16 little-endian dan big-endian, noncharacter seperti 0xFFFEjuga tidak mungkin karena kebalikannya 0xFEFFadalah karakter Unicode yang valid.
  • FAQ yang disebutkan di atas menyarankan untuk tidak menggunakan karakter nonchar karena masih akan menghasilkan urutan Unicode yang valid, jadi sesuatu seperti 0xFFFFini juga keluar dari gambar.

Apa nilai sentinel bukti masa depan yang tersisa untuk saya gunakan?


1 ) Format PNG memiliki byte pertama sebagai nilai non-ASCII 0x89, diikuti oleh string PNG. Alat yang membaca beberapa byte pertama dari PNG dapat menentukan itu adalah file biner karena tidak dapat diartikan 0x89. Sebaliknya, file GIF dimulai langsung dengan string ASCII yang valid dan mudah dibaca GIFdiikuti oleh tiga karakter ASCII yang lebih valid. Untuk GIF suatu alat mungkin menentukan itu adalah file teks yang dapat dibaca. Ini salah dan ide memulai file dengan urutan byte non-tekstur berasal dari Merancang Format File oleh Andy McFadden.

Daniel AA Pelsmaeker
sumber
3
Since it is a binary format, the first bytes of the file should not form valid textual characters- Anda harus melihat file ajaib (/ usr / share / magic, atau / etc / magic di banyak sistem unix) yang menunjukkan bagaimana aplikasi ini mengidentifikasi jenis file. Sebuah file PNG dimulai dengan \x89PNG\x0d\0a\x1a\x0a- perhatikan "PNG" di sana, itu adalah string mentah. Urutan \x89dan sejenisnya adalah byte yang tidak dapat dicetak.
@MichaelT Ya, karena PNG adalah format biner, byte pertama tidak membentuk karakter tekstual yang valid. Itu yang saya maksud. Saya gagal melihat maksud Anda?
Daniel AA Pelsmaeker
7
Itu contohnya. Gif dimulai dengan GIF8. File film SGI dimulai dengan MOVI. Satu gaya file arsip zip dimulai dengan ZZ, format pkzip yang lebih populer dimulai dengan PK. Batasan bahwa byte pertama menjadi karakter teks yang tidak valid tampaknya tidak cocok dengan apa yang ditemukan di alam liar. Saya ingin tahu mengapa ini merupakan persyaratan.
3
Apakah Anda benar-benar peduli dengan perilaku program lain ketika mereka melihat file yang tidak dikenal? Bagi saya, urutan tanda tangan (seperti file PNG) jauh lebih berguna daripada urutan sentinel - ketika konten dikirim melalui protokol streaming sederhana, penerima dapat segera memutuskan bagaimana menangani byte berikut. Urutan sentinel-Oman adalah di samping tanpa-urutan setelah semua orang mulai menggunakannya untuk mengidentifikasi format mereka sendiri.
Codism
2
@Virtlink, saya tidak terlalu peduli byte apa yang Anda gunakan dalam format file Anda. Tetapi Anda membuat pernyataan bahwa 'salah' menggunakan karakter ascii ... namun saya belum melihat apa pun di sini yang mendukung klaim itu, dan ada banyak pengalaman empiris yang menunjukkan bahwa itu benar-benar tidak masalah (yaitu, file yang tak terhitung jumlahnya format yang telah menggunakan karakter ASCII tanpa masalah selama beberapa dekade)
GrandmasterB

Jawaban:

16

0xDC 0xDC

  • Jelas UTF-8 dan ASCII tidak valid
  • Pengganti jejak yang tidak berpasangan dalam posisi memimpin terlepas dari endianess di UTF-16. Itu tidak mendapatkan UTF-16 lebih valid dari itu.
Esailija
sumber
Tapi ISO-8859-1 sangat masuk akal, dan mungkin masuk akal dalam rangkaian karakter lain yang menggunakan pengkodean 8-bit.
parsifal
4
+1 OP tidak meminta ISO 8859-1, hanya US-ASCII dan UTF- *.
Ross Patterson
@RossPatterson - benar, tapi saya menduga itu sebagian besar karena OP belum benar-benar memikirkan masalahnya. Tanpa statistik yang mendukung saya, saya berani bertaruh bahwa algoritma "is this text" acak lebih cenderung memberikan preferensi untuk ISO-8859-1 daripada UTF-16, hanya karena ada sejumlah besar 8-bit teks di dunia.
parsifal
3
@parsifal Setiap biner adalah ISO-8859-1 yang valid sehingga tidak perlu dipertimbangkan hanya karena tidak mungkin untuk membuat ISO-8859-1 yang tidak valid.
Esailija
1
@parsifal benar dan jika itu adalah persyaratan yang bisa Anda gunakan 0x00atau apa pun, tetapi op tidak menginginkan itu.
Esailija
5
  • Dalam UTF-8, byte C0, C1, dan F5 - FF adalah ilegal. Byte pertama harus berupa ASCII atau byte dalam rentang C2-F4, byte awal lainnya tidak valid UTF-8.

  • Dalam UTF-16, file biasanya dimulai dengan Byte Order Mark (U + FEFF), jika tidak aplikasi harus menebak urutan byte. Codepoints dalam kisaran D800-DBFF adalah byte memimpin untuk pasangan pengganti, dan DC00-DFFF adalah byte tambahan untuk pasangan pengganti.

Jadi, saya akan menggunakan kombo byte F5DC. Kedua nilai tersebut adalah:

  • Bukan ASCII
  • Tidak valid UTF-8
  • Entah ditafsirkan sebagai UTF-16 trailing byte dalam pasangan pengganti (tidak sah), atau codepoint U + F5DC, yang merupakan karakter penggunaan pribadi, tetapi hanya oleh aplikasi yang keras kepala mencoba untuk menafsirkan ini sebagai UTF-16 bahkan tanpa BOM .

Jika Anda membutuhkan lebih banyak pilihan, F5DDhingga F5DFsemua memiliki 3 sifat yang sama, seperti yang F6DC- F6DF, F7DC- F7DFdan F8DC- F8DF, untuk total 16 combo byte yang berbeda untuk memilih dari.

Martijn Pieters
sumber
Jadi, dengan saran Esailija untuk menggunakan U + DCDC, 0xDCapakah valid UTF-8?
Daniel AA Pelsmaeker
2
@Virtlink 0xDCadalah byte utama UTF-8 untuk urutan 2-byte. Itu harus diikuti oleh 10xxxxxxbyte lanjutan agar valid. 0xDCbukan byte kelanjutan yang valid, jadi 0xDC 0xDCUTF-8 tidak valid.
Esailija
@Virtlink: Tidak, karena byte kedua tidak valid, itu harus berada dalam jangkauan 80- BF.
Martijn Pieters
2

Jika Anda mencoba menggunakan karakter yang tidak dapat dicetak untuk menunjukkan "bukan teks," maka Anda akan sulit mengalahkan 0x89:

  • Itu di luar kisaran AS-ASCII
  • Dalam ISO-8859-1 itu adalah karakter yang tidak dapat dicetak ("KARAKTER TABULASI DENGAN JUSTIFIKASI"). Begitu juga dengan Shift-JIS, yang menurut saya masih umum digunakan. Namun, penyandian 8-bit lainnya mungkin memperlakukan ini sebagai karakter yang valid.
  • Dalam UTF-8 itu adalah byte pertama yang tidak valid untuk urutan multi-byte (bit atas adalah 10, yang dicadangkan untuk karakter 2..N dari urutan multi-byte)

Secara umum, ketika Anda membentuk angka ajaib, "non-teks" adalah poin minor. Saya harus mencari referensi, tetapi salah satu format grafik standar (TIFF, saya pikir) memiliki sesuatu seperti enam informasi berbeda yang berguna dari angka ajaibnya.

parsifal
sumber