Kullanabileceğim bir Unicode sentinel değeri?


14

Bir dosya formatı tasarlıyorum ve doğru yapmak istiyorum. Bir ikili biçim olduğundan, dosyanın ilk bayt (veya bayt) gerekir değil (sadece PNG dosya başlığında gibi geçerli metinsel karakterleri oluşturmak 1 ). Bu, biçimi tanımayan araçların ilk birkaç bayta bakarak bir metin dosyası olmadığını görmelerini sağlar.

Yukarıdaki herhangi bir kod noktası 0x7Fgeçersiz US-ASCII olduğundan, bu kolaydır. Ama Unicode için bu tamamen farklı bir hikaye. Dışında geçerli Unicode karakter vardır , özel kullanım karakterler , noncharacters ve nöbetçi Ben bulunduğu gibi, Unicode Özel Kullanım Karakterler, Noncharacters & Nöbetçiler SSS .

Dosyanın başlangıcında geçersiz US-ASCII, UTF-8, UTF-16LE ve UTF-16BE ile sonuçlanabilecek bir bayt dizisi ne olurdu?

  • Açıkça görülüyor ki, ilk bayt aşağıda 0x80geçerli bir US-ASCII (kontrol) karakteri olabileceği için bir değere sahip 0x00olamaz , bu yüzden kullanılamaz.
  • Ayrıca, özel kullanım karakterleri geçerli Unicode karakterler olduğundan, bu kod noktalarını da kullanamıyorum.
  • O çalışmak zorunda olduğundan, her iki küçük endian ve büyük endian UTF-16, bir noncharacter gibi 0xFFFEonun tersi olarak da mümkün değildir 0xFEFF, geçerli bir Unicode karakter.
  • Yukarıda belirtilen SSS herhangi birini kullanarak değil önerir noncharacters şey gibi pek hala geçerli bir Unicode sırayla neden olacağını olarak 0xFFFFdışarı resmin aynı zamanda.

Kullanmam için bırakılacak geleceğe hazır sentinel değerleri ne olur?


1 ) PNG formatı ilk baytı ASCII olmayan 0x89değeri, ardından dizeyi içerir PNG. Bir PNG'nin ilk birkaç baytını okuyan bir araç, yorumlayamadığı için ikili bir dosya olduğunu belirleyebilir 0x89. Öte yandan, bir GIF dosyası doğrudan geçerli ve okunabilir ASCII dizesi ve GIFardından üç geçerli ASCII karakteriyle başlar. GIF için bir araç, okunabilir bir metin dosyası olduğunu belirleyebilir. Bu yanlıştır ve dosyayı dokusal olmayan bir bayt dizisiyle başlatma fikri Andy McFadden tarafından Dosya Formatları Tasarlama'dan geldi .


3
Since it is a binary format, the first bytes of the file should not form valid textual characters- Bu uygulamanın dosya türlerini nasıl tanımladığını gösteren sihirli dosyaya (/ usr / share / magic veya / etc / magic) bakmalısınız. Bir PNG dosyası ile başlar \x89PNG\x0d\0a\x1a\x0a- içindeki "PNG" yi not edin, bu ham bir dize. Diziler \x89ve benzerleri yazdırılamayan baytlardır.

@MichaelT Evet, PNG bir ikili biçim olduğundan, ilk bayt geçerli bir metin karakteri oluşturmaz. Demek istediğim şey o. Demek istediğini anlayamadım?
Daniel AA Pelsmaeker

7
Bu bir örnekti. Bir .gif ile başlar GIF8. Bir SGI movi dosyası ile başlar MOVI. Bir stil zip arşiv dosyası ile başlar ZZ, daha popüler pkzip formatı ile başlar PK. İlk baytın geçersiz bir metin karakteri olması kısıtlaması, vahşi ortamda bulunanlarla eşleşmiyor gibi görünüyor. Bunun neden bir gereklilik olduğunu merak ediyorum.

3
Bilinmeyen bir dosya gördüğünde diğer programların nasıl davrandığını gerçekten önemsiyor musunuz? Bana göre, bir imza dizisi (PNG dosyaları gibi) bir sentinel dizisinden çok daha kullanışlıdır - içerik basit bir akış protokolü yoluyla gönderildiğinde, alıcı hemen aşağıdaki baytların nasıl işleneceğine karar verebilir. Omani-sentinel dizisi, herkes kendi biçimini tanımlamak için kullanmaya başladığında, dizilimin yanındadır.
Codism

2
@Virtlink, özellikle dosya biçiminizde kullandığınız baytları önemsemiyorum. Ama ascii karakterleri kullanmanın 'yanlış' olduğunu iddia ettiniz ... yine de burada bu iddiayı destekleyen hiçbir şey görmedim ve bunun gerçekten önemli olmadığını gösteren çok sayıda deneysel deneyim var (yani sayısız dosya) yıllardır sorunsuz ASCII karakterleri kullanan biçimler)
GrandmasterB

Yanıtlar:


16

0xDC 0xDC

  • Açıkçası geçersiz UTF-8 ve ASCII
  • UTF-16'daki endianiteye bakılmaksızın eşleştirilmemiş parkur kurşun konumunda. Bundan daha geçersiz UTF-16 almaz.

Ancak mükemmel makul ISO-8859-1 ve muhtemelen 8 bit kodlama kullanan diğer karakter kümelerinde makul.
parsifal

4
+1 OP ISO 8859-1'i istemedi, sadece US-ASCII ve UTF- *.
Ross Patterson

@RossPatterson - doğru, ama bunun çoğunlukla OP'nin problemi gerçekten düşünmediği için şüpheleniyorum. Beni destekleyecek herhangi bir istatistik olmadan, rastgele bir "bu metin" algoritmasının UTF-16'dan çok ISO-8859-1'e tercih etme olasılığının daha yüksek olduğundan bahse girmeye istekliyim, çünkü sadece 8 bitlik çok büyük bir miktar var dünyadaki metin.
parsifal

3
@parsifal Herhangi bir ikili geçerli ISO-8859-1'dir, bu nedenle dikkate alınması gerekmez, çünkü geçersiz ISO-8859-1 yapmak imkansızdır.
Esailija

1
@parsifal true ve gereksinim buysa, sadece 0x00ya da her neyse kullanabilirsiniz , ama op bunu istemiyordu.
Esailija

5
  • UTF-8'de, C0, C1 ve F5 - FF baytları yasadışıdır. İlk bayt ASCII veya C2-F4 aralığında bir bayt olmalıdır, diğer herhangi bir başlangıç ​​baytı geçerli UTF-8 değildir.

  • UTF-16'da, dosya normal olarak Bayt Sırası İşareti (U + FEFF) ile başlar, aksi takdirde uygulamaların bayt sırasını tahmin etmesi gerekir. D800-DBFF aralığındaki kod noktaları, bir vekil çift için kurşun baytlardır ve DC00-DFFF, bir vekil çift için arka bayttır.

Böylece, bayt kombinasyonunu kullanırdım F5DC. Bu iki değer şunlardır:

  • ASCII değil
  • Geçerli değil UTF-8
  • Yedek bir çiftte (yasal olmayan) UTF-16 sondaki bayt olarak veya özel kullanım karakteri olan U + F5DC kod noktası olarak yorumlanır , ancak yalnızca bunu bir ürün ağacı olmadan bile UTF-16 olarak yorumlamaya çalışan uygulamalar tarafından .

Eğer gerekiyorsa daha fazla seçenek, F5DDüzerine F5DFtüm olarak yok, aynı 3 özelliklere sahip F6DC- F6DF, F7DC- F7DFve F8DC- F8DF, 16 farklı bayt kombinasyonları olmak üzere toplam almak için.


Yani, tarafından Esailija önerisi U + DCDC kullanmak, 0xDCgeçerli UTF-8 olurdu?
Daniel AA Pelsmaeker

2
@Virtlink 0xDC, 2 baytlık bir dizi için bir UTF-8 kurşun baytıdır . 10xxxxxxGeçerli olabilmesi için bir devam baytı tarafından takip edilmesi gerekir . 0xDCgeçerli bir devam baytı 0xDC 0xDCdeğil, geçerli UTF-8 değil.
Esailija

@Virtlink: Hayır, ikinci bayt geçerli olmadığından, 80- aralığında olması gerekir BF.
Martijn Pieters

2

"Metin değil" belirtmek için yazdırılamaz bir karakter kullanmaya çalışıyorsanız, 0x89'u geçmenin zor olduğunu görürsünüz:

  • US-ASCII serisinin dışında
  • ISO-8859-1'de yazdırılamaz bir karakterdir ("YETKİLİ KARAKTER TABÜLASYONU"). Aynı şekilde hala ortak kullanımda olduğuna inandığım Shift-JIS ile. Bununla birlikte, diğer 8 bit kodlamalar bunu geçerli bir karakter olarak kabul edebilir.
  • UTF-8'de, çok baytlık bir dizi için geçersiz bir ilk bayt (üst bitler 10'dur ve bunlar, çok baytlı bir dizinin 2. karakterleri için ayrılmıştır).

Genel olarak, sihirli sayılar oluşturduğunuzda, "metin olmayan" küçük bir noktadır. Referansa bakmam gerekecek, ancak standart grafik formatlarından birinin (TIFF, sanırım) sihirli numarasından altı farklı yararlı bilgi parçası gibi bir şey var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.