Một giá trị sentinel Unicode tôi có thể sử dụng?


14

Tôi đang mong muốn một định dạng tập tin và tôi muốn làm điều đó đúng. Vì nó là định dạng nhị phân, nên byte (hoặc byte) đầu tiên của tệp không được tạo thành các ký tự văn bản hợp lệ (giống như trong tiêu đề tệp PNG 1 ). Điều này cho phép các công cụ không nhận dạng định dạng vẫn thấy rằng nó không phải là tệp văn bản bằng cách xem xét một vài byte đầu tiên.

Bất kỳ mật mã nào ở trên 0x7Fđều không hợp lệ US-ASCII, vì vậy điều đó thật dễ dàng. Nhưng đối với Unicode thì đó là một câu chuyện hoàn toàn khác. Ngoài các ký tự Unicode hợp lệ có ký tự dùng riêng , noncharacterslính canh , như tôi đã tìm thấy trong Unicode Sử dụng cá nhân nhân vật, Noncharacters & Sentinel FAQ .

Điều gì sẽ là một chuỗi các byte mà tôi có thể sử dụng khi bắt đầu tập tin dẫn đến US-ASCII, UTF-8, UTF-16LE và UTF-16BE không hợp lệ?

  • Rõ ràng byte đầu tiên không thể có giá trị dưới đây 0x80vì đó sẽ là ký tự (kiểm soát) US-ASCII hợp lệ, do đó 0x00không thể được sử dụng.
  • Ngoài ra, vì các ký tự sử dụng riêng là các ký tự Unicode hợp lệ, tôi cũng không thể sử dụng các mật mã đó.
  • Vì nó phải hoạt động với cả UTF-16 cuối nhỏ và cuối lớn, nên một loại không có vi khuẩn như 0xFFFElà không thể vì ngược lại 0xFEFFlà ký tự Unicode hợp lệ.
  • FAQ nêu trên đề nghị không sử dụng bất kỳ noncharacters như rằng vẫn sẽ cho kết quả trong một chuỗi Unicode hợp lệ, vì vậy cái gì đó như 0xFFFFcũng là ra khỏi bức tranh.

Giá trị sentinel trong tương lai còn lại để tôi sử dụng là gì?


1 ) Định dạng PNG có byte đầu tiên là 0x89giá trị không phải ASCII , theo sau là chuỗi PNG. Một công cụ đọc một vài byte đầu tiên của PNG có thể xác định nó là một tệp nhị phân vì nó không thể diễn giải 0x89. Mặt khác, một tệp GIF bắt đầu trực tiếp với chuỗi ASCII hợp lệ và có thể đọc được, GIFtheo sau là ba ký tự ASCII hợp lệ hơn. Đối với GIF, một công cụ có thể xác định nó là một tệp văn bản có thể đọc được. Điều này là sai và ý tưởng bắt đầu tệp với một chuỗi byte không có kết cấu xuất phát từ Thiết kế định dạng tệp của Andy McFadden.


3
Since it is a binary format, the first bytes of the file should not form valid textual characters- Bạn nên xem tệp ma thuật (/ usr / share / magic hoặc / etc / magic trên nhiều hệ thống unix) cho thấy cách ứng dụng này xác định các loại tệp. Một tệp PNG bắt đầu bằng \x89PNG\x0d\0a\x1a\x0a- lưu ý "PNG" trong đó, đó là một chuỗi thô. Các chuỗi \x89và tương tự là các byte không in được.

@MichaelT Có, vì PNG là định dạng nhị phân, byte đầu tiên không tạo thành một ký tự văn bản hợp lệ. Ý tôi là thế Tôi không thấy quan điểm của bạn?
Daniel AA Pelsmaeker

7
Đó là một ví dụ. Một .gif bắt đầu với GIF8. Một tập tin SGI Movi bắt đầu với MOVI. Một kiểu tệp lưu trữ zip bắt đầu bằng ZZ, định dạng pkzip phổ biến hơn bắt đầu bằng PK. Ràng buộc rằng byte đầu tiên là một ký tự văn bản không hợp lệ dường như không khớp với những gì được tìm thấy trong tự nhiên. Tôi tò mò tại sao đây là một yêu cầu.

3
Bạn có thực sự quan tâm làm thế nào các chương trình khác hoạt động khi họ nhìn thấy một tập tin không xác định? Đối với tôi, một chuỗi chữ ký (như các tệp PNG) hữu ích hơn nhiều so với chuỗi sentinel - khi nội dung được gửi qua một giao thức luồng đơn giản, người nhận có thể quyết định ngay cách xử lý các byte sau. Một chuỗi sentinel của Ô-man nằm bên cạnh không có trình tự một khi mọi người bắt đầu sử dụng nó để xác định định dạng của riêng họ.
Codism

2
@Virtlink, tôi không đặc biệt quan tâm những byte bạn sử dụng trong định dạng tệp của bạn. Nhưng bạn đã khẳng định rằng việc sử dụng các ký tự ascii là 'sai' ... nhưng tôi chưa thấy bất cứ điều gì ở đây hỗ trợ cho tuyên bố đó, và có nhiều kinh nghiệm thực nghiệm cho thấy nó thực sự không quan trọng (ví dụ: vô số tệp các định dạng đã sử dụng các ký tự ASCII mà không gặp vấn đề gì trong nhiều thập kỷ)
GrandmasterB

Câu trả lời:


16

0xDC 0xDC

  • Rõ ràng UTF-8 và ASCII không hợp lệ
  • Dấu vết không ghép đôi thay thế ở vị trí dẫn đầu bất kể endianess trong UTF-16. Nó không nhận được nhiều UTF-16 không hợp lệ hơn thế.

Nhưng ISO-8859-1 hoàn toàn hợp lý và có lẽ hợp lý trong bất kỳ bộ ký tự nào khác sử dụng mã hóa 8 bit.
phân tích

4
+1 OP đã không yêu cầu ISO 8859-1, chỉ US-ASCII và UTF- *.
Ross Patterson

@RossPatterson - đúng, nhưng tôi nghi ngờ điều đó chủ yếu là do OP chưa thực sự nghĩ đến vấn đề này. Không có bất kỳ số liệu thống kê nào để hỗ trợ tôi, tôi sẵn sàng đặt cược rằng thuật toán "văn bản này" ngẫu nhiên có nhiều khả năng ưu tiên cho ISO-8859-1 hơn UTF-16, đơn giản vì có số lượng 8 bit rất lớn văn bản trên thế giới.
phân tích

3
@parsifal Bất kỳ nhị phân nào cũng hợp lệ ISO-8859-1, do đó không cần phải xem xét đơn giản vì không thể tạo ISO-8859-1 không hợp lệ.
Esailija

1
@parsifal đúng và nếu đó là yêu cầu bạn chỉ có thể sử dụng 0x00hoặc bất cứ điều gì, nhưng op không muốn điều đó.
Esailija

5
  • Trong UTF-8, các byte C0, C1 và F5 - FF là bất hợp pháp. Byte đầu tiên phải là ASCII hoặc một byte trong phạm vi C2-F4, bất kỳ byte bắt đầu nào khác đều không hợp lệ UTF-8.

  • Trong UTF-16, tệp thường bắt đầu bằng Dấu thứ tự Byte (U + FEFF), nếu không các ứng dụng phải đoán theo thứ tự byte. Các điểm mã trong phạm vi D800-DBFF là các byte dẫn cho một cặp thay thế và DC00-DFFF là các byte theo dõi cho một cặp thay thế.

Vì vậy, tôi sẽ sử dụng kết hợp byte F5DC. Hai giá trị này là:

  • Không phải ASCII
  • Không hợp lệ UTF-8
  • Được hiểu là byte theo dõi UTF-16 trong một cặp thay thế (không hợp pháp) hoặc mã hóa U + F5DC, là một ký tự sử dụng riêng, nhưng chỉ bởi các ứng dụng cố tình diễn giải điều này là UTF-16 ngay cả khi không có BOM .

Nếu bạn cần thêm tùy chọn, F5DDthông qua để F5DFtất cả đều có cùng 3 thuộc tính, như làm F6DC- F6DF, F7DC- F7DFF8DC- F8DF, với tổng số 16 combo byte khác nhau để chọn từ.


Vì vậy, theo đề xuất của Esailija để sử dụng U + DCDC, 0xDCsẽ là UTF-8 hợp lệ?
Daniel AA Pelsmaeker

2
@Virtlink 0xDClà byte dẫn UTF-8 cho chuỗi 2 byte. Nó phải được theo sau bởi một 10xxxxxxbyte tiếp tục để nó hợp lệ. 0xDCkhông phải là byte tiếp tục hợp lệ, vì vậy 0xDC 0xDCUTF-8 không hợp lệ.
Esailija

@Virtlink: Không, vì byte thứ hai không hợp lệ, nên nó phải nằm trong phạm vi 80- BF.
Martijn Pieters

2

Nếu bạn đang cố gắng sử dụng một ký tự không in được để biểu thị "không phải văn bản", thì bạn sẽ khó đánh bại 0x89:

  • Nó nằm ngoài phạm vi US-ASCII
  • Trong ISO-8859-1, đó là một ký tự không thể in được ("TABULATION TABULATION With JUSTMENTATION"). Tương tự như vậy với Shift-JIS, mà tôi tin rằng vẫn còn được sử dụng phổ biến. Tuy nhiên, các mã hóa 8 bit khác có thể coi đây là một ký tự hợp lệ.
  • Trong UTF-8, đó là byte đầu tiên không hợp lệ cho chuỗi nhiều byte (các bit trên cùng là 10, được dành riêng cho các ký tự 2..N của chuỗi nhiều byte)

Nói chung, khi bạn hình thành các số ma thuật, "phi văn bản" là một điểm nhỏ. Tôi sẽ phải tra cứu tài liệu tham khảo, nhưng một trong những định dạng đồ họa tiêu chuẩn (TIFF, tôi nghĩ) có thứ gì đó giống như sáu mẩu thông tin hữu ích khác nhau từ số ma thuật của nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.