Làm cách nào để kiểm tra mã hóa tập tin văn bản. Nó có hợp lệ không, và nó là gì?


46

Tôi có một số .htmtệp mở trong Gedit mà không có bất kỳ cảnh báo / lỗi nào, nhưng khi tôi mở cùng các tệp này Jedit, nó sẽ cảnh báo tôi về mã hóa UTF-8 không hợp lệ ...

Thẻ meta HTML ghi "charset = ISO-8859-1". Jedit cho phép Danh sách mã hóa dự phòngDanh sách các trình phát hiện tự động mã hóa (hiện là "BOM XML-PI"), vì vậy vấn đề trước mắt của tôi đã được giải quyết. Nhưng điều này khiến tôi suy nghĩ về: Điều gì xảy ra nếu dữ liệu meta không có ở đó?

Khi thông tin mã hóa không có sẵn, có chương trình CLI nào có thể đưa ra "dự đoán tốt nhất" về mã hóa nào có thể áp dụng không?

Và, mặc dù nó là một vấn đề hơi khác nhau; Có chương trình CLI nào kiểm tra tính hợp lệ của mã hóa đã biết không?


Tương tự như "Cách tự động phát hiện mã hóa tệp văn bản?" superuser.com/questions/301552/
--373791

Câu trả lời:


60

Các filelệnh làm cho "best-đoán" về mã hóa. Sử dụng -itham số để buộc filein thông tin về mã hóa.

Trình diễn, thuyết trình:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

Đây là cách tôi tạo các tệp:

$ echo ä > umlaut-utf8.txt 

Ngày nay mọi thứ đều là utf-8. Nhưng hãy thuyết phục bản thân:

$ hexdump -C umlaut-utf8.txt 
00000000  c3 a4 0a                                          |...|
00000003

So sánh với https://en.wikipedia.org/wiki/Ä#Computer_encoding

Chuyển đổi sang các bảng mã khác:

$ iconv -f utf8 -t iso88591 umlaut-utf8.txt > umlaut-iso88591.txt 
$ iconv -f utf8 -t utf16 umlaut-utf8.txt > umlaut-utf16.txt 

Kiểm tra bãi chứa hex:

$ hexdump -C umlaut-iso88591.txt 
00000000  e4 0a                                             |..|
00000002
$ hexdump -C umlaut-utf16.txt 
00000000  ff fe e4 00 0a 00                                 |......|
00000006

Tạo một cái gì đó "không hợp lệ" bằng cách trộn cả ba:

$ cat umlaut-iso88591.txt umlaut-utf8.txt umlaut-utf16.txt > umlaut-mixed.txt 

Những gì filenói:

$ file -i *
umlaut-iso88591.txt: text/plain; charset=iso-8859-1
umlaut-mixed.txt:    application/octet-stream; charset=binary
umlaut-utf16.txt:    text/plain; charset=utf-16le
umlaut-utf8.txt:     text/plain; charset=utf-8

không có -i:

$ file *
umlaut-iso88591.txt: ISO-8859 text
umlaut-mixed.txt:    data
umlaut-utf16.txt:    Little-endian UTF-16 Unicode text, with no line terminators
umlaut-utf8.txt:     UTF-8 Unicode text

Các filelệnh không có ý tưởng về "hợp lệ" hoặc "không hợp lệ". Nó chỉ nhìn thấy một số byte và cố gắng đoán mã hóa có thể là gì. Là con người, chúng ta có thể nhận ra rằng một tệp là một tệp văn bản với một số âm sắc trong một mã hóa "sai". Nhưng là một máy tính, nó sẽ cần một số loại trí tuệ nhân tạo.

Người ta có thể lập luận rằng các heuristic của filemột số loại trí tuệ nhân tạo. Tuy nhiên, ngay cả khi nó là, nó là một rất hạn chế.

Dưới đây là thông tin thêm về filelệnh: http://www.linfo.org/file_command.html


Cảm ơn, điều đó đã làm việc ... Tôi đã thử 'tập , but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. tin tập tin -i` báo cáo unknown-8bit. Vì vậy, đây dường như cũng là câu trả lời cho: "Cách phát hiện mã hóa không hợp lệ / không xác định"
Peter.O

Đối với những người đến đây và đang ở trên máy Mac, nó file -Icó chữ 'i' thay vì chữ thường.
samuraiseoul

21

Không phải lúc nào cũng có thể tìm ra chắc chắn mã hóa của tệp văn bản là gì. Ví dụ, chuỗi byte \303\275( c3 bdtheo hệ thập lục phân) có thể ýở dạng UTF-8 ýhoặc Ă˝theo tiếng Latin1 hoặc tiếng Latin2 hoặc BIG-5, v.v.

Một số mã hóa có chuỗi byte không hợp lệ, vì vậy chắc chắn có thể loại trừ chúng. Điều này đúng với UTF-8; hầu hết các văn bản trong hầu hết các mã hóa 8 bit đều không hợp lệ UTF-8. Bạn có thể kiểm tra cho UTF-8 còn hiệu lực với isutf8từ moreutils hoặc iconv -f utf-8 -t utf-8 >/dev/null, giữa những người khác.

Có những công cụ cố gắng đoán mã hóa của một tệp văn bản. Họ có thể phạm sai lầm, nhưng họ thường làm việc trong thực tế miễn là bạn không cố tình lừa họ.

  • file
  • PerlEncode::Guess (một phần của phân phối chuẩn) thử mã hóa liên tiếp trên chuỗi byte và trả về mã hóa đầu tiên trong đó chuỗi là văn bản hợp lệ.
  • Enca là một công cụ đoán và chuyển đổi mã hóa. Bạn có thể đặt cho nó một tên ngôn ngữ và văn bản mà bạn cho là bằng ngôn ngữ đó (các ngôn ngữ được hỗ trợ chủ yếu là các ngôn ngữ Đông Âu) và nó cố gắng đoán mã hóa.

Nếu có siêu dữ liệu (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-, thì) trong tệp, các trình soạn thảo nâng cao như Emacs hoặc Vim thường có thể phân tích siêu dữ liệu đó. Điều đó không dễ để tự động hóa từ dòng lệnh mặc dù.


Cảm ơn về tổng quan tốt ... Có, "dự đoán tốt nhất" có thể là tùy chọn duy nhất khi mã hóa không được biết đến ... Sử dụng iconv, tôi chỉ chạy tất cả 1168 mã hóa (bao gồm cả bí danh) được liệt kê bằng iconv -lmột trong các tệp .htm của tôi ... Có 683 mã hóa đã vượt qua .. Bảng mã thực tế của tệp = ISO-8859-1 .. tạo ra tất cả các giá trị trong phạm vi một thanh ASCII .. char không phải ASCII là \ xA9.
Peter.O

0

Ngoài ra trong trường hợp bạn tập tin -i cung cấp cho bạn không biết

Bạn có thể sử dụng lệnh php này có thể đoán bộ ký tự như dưới đây:

Trong php bạn có thể kiểm tra như dưới đây:

Chỉ định danh sách mã hóa rõ ràng:

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), 'UTF-8, ASCII, JIS, EUC-JP, SJIS, iso-8859-1') . PHP_EOL;"

Chính xác hơn " mb_list_encodings ":

php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"

Ở đây trong ví dụ đầu tiên, bạn có thể thấy rằng tôi đặt một danh sách mã hóa (phát hiện thứ tự danh sách) có thể khớp. Để có kết quả chính xác hơn, bạn có thể sử dụng tất cả các mã hóa có thể thông qua: mb_list_encodings ()

Lưu ý các hàm mb_ ​​* yêu cầu php-mbopes

apt-get install php-mbstring 

Xem câu trả lời: https://stackoverflow.com/a/57010566/3382822

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.