it-swarm-vi.com

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

Tôi có một số .htm các tệ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ác tệp tương tự trong 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 một Danh sách mã hóa dự phòng Danh sách các trình phát hiện tự động mã hóa (hiện tại 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?

55
Peter.O

Lệnh file tạo ra "dự đoán tốt nhất" về mã hóa. Sử dụng -i tham số để buộc file để in thông tin về mã hóa.

Trình diễn:

$ 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ì file nó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

Lệnh file không có ý tưởng "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 file là một 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ề lệnh file: http://www.linfo.org/file_command.html

70
lesmana

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 bd trong thập lục phân) có thể là ý trong UTF-8 hoặc ý bằng tiếng Latin1 hoặc Ă˝ bằng tiếng Latin2 hoặc trong 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 UTF-8 hợp lệ bằng isutf8 từ moreutils hoặc với 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
  • Perl Encode::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-*-, Gặp) trong tệp, các biên tập viên nâng cao như Emacs hoặc Vim thường có thể phân tích cú pháp siêu dữ liệu đó. Điều đó không dễ để tự động hóa từ dòng lệnh.

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

1
Mohamed23gharbi