Bagaimana saya bisa menguji penyandian file teks ... Apakah itu valid, dan apa itu?

46

Saya memiliki beberapa .htmfile yang terbuka di Gedit tanpa peringatan / kesalahan, tetapi ketika saya membuka file yang sama ini Jedit, ia memperingatkan saya tentang pengkodean UTF-8 yang tidak valid ...

Tag meta HTML menyatakan "charset = ISO-8859-1". Jedit memungkinkan Daftar penyandian mundur dan Daftar pendeteksi otomatis penyandian (saat ini "BOM XML-PI"), jadi masalah langsung saya telah diselesaikan. Tapi ini membuat saya berpikir: Bagaimana jika meta data tidak ada di sana?

Ketika informasi pengkodean tidak tersedia, apakah ada program CLI yang dapat membuat "tebakan terbaik" yang mana pengkodean mungkin berlaku?

Dan, meskipun ini adalah masalah yang sedikit berbeda; apakah ada program CLI yang menguji validitas pengkodean yang dikenal ?

Peter.O
sumber
Mirip dengan "Bagaimana cara mendeteksi pengkodean file teks secara otomatis?" superuser.com/questions/301552/…
buzz3791
Lihat juga stackoverflow.com/q/805418/821436 :-)
Reinstate Monica - M. Schröder

Jawaban:

60

The fileperintah membuat "best-tebakan" tentang pengkodean. Gunakan -iparameter untuk memaksa filemencetak informasi tentang penyandian.

Demonstrasi:

$ 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

Inilah cara saya membuat file:

$ echo ä > umlaut-utf8.txt 

Sekarang semuanya utf-8. Tapi yakinkan diri Anda:

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

Bandingkan dengan https://en.wikipedia.org/wiki/Ä#Computer_encoding

Konversi ke penyandian lain:

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

Periksa hex dump:

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

Buat sesuatu yang "tidak valid" dengan mencampur ketiganya:

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

Apa yang filedikatakan:

$ 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

tanpa -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

The fileperintah tidak memiliki gagasan tentang "valid" atau "tidak sah". Itu hanya melihat beberapa byte dan mencoba menebak apa pengkodean mungkin. Sebagai manusia, kita mungkin dapat mengenali bahwa file adalah file teks dengan beberapa umlaut dalam pengkodean "salah". Tetapi sebagai komputer itu akan membutuhkan semacam kecerdasan buatan.

Orang mungkin berpendapat bahwa heuristik fileadalah semacam kecerdasan buatan. Namun, bahkan jika itu, itu sangat terbatas.

Berikut ini informasi lebih lanjut tentang fileperintah: http://www.linfo.org/file_command.html

lesmana
sumber
Terima kasih, itu berhasil ... Saya sudah mencoba 'file , but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. file -i` yang dilaporkan unknown-8bit. Jadi, ini juga tampaknya menjadi jawaban untuk: "Bagaimana mendeteksi pengkodean yang tidak valid / tidak dikenal"
Peter.O
Bagi yang sampai di sini dan menggunakan mac, itu file -Idengan huruf kapital 'i' bukan huruf kecil.
samuraiseoul
21

Tidak selalu mungkin untuk mengetahui dengan pasti apa penyandian file teks. Misalnya, urutan byte \303\275( c3 bddalam heksadesimal) bisa ýdalam UTF-8, atau ýdalam latin1, atau Ă˝dalam latin2, atau dalam BIG-5, dan seterusnya.

Beberapa pengkodean memiliki urutan byte yang tidak valid, jadi mungkin untuk mengesampingkannya. Ini benar khususnya pada UTF-8; sebagian besar teks dalam kebanyakan penyandian 8-bit tidak valid UTF-8. Anda dapat menguji UTF-8 yang valid dengan isutf8dari moreutils atau dengan iconv -f utf-8 -t utf-8 >/dev/null, antara lain.

Ada alat yang mencoba menebak penyandian file teks. Mereka dapat membuat kesalahan, tetapi mereka sering bekerja dalam praktik selama Anda tidak sengaja mencoba membodohi mereka.

  • file
  • PerlEncode::Guess (bagian dari distribusi standar) mencoba penyandian berurutan pada string byte dan mengembalikan penyandian pertama di mana string adalah teks yang valid.
  • Enca adalah penebak dan konverter pengkodean. Anda dapat memberikannya nama bahasa dan teks yang Anda anggap dalam bahasa itu (bahasa yang didukung sebagian besar bahasa Eropa Timur), dan ia mencoba menebak pengodeannya.

Jika ada metadata (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-, ...) dalam file, editor tingkat lanjut seperti Emacs atau Vim sering dapat mengurai metadata itu. Itu tidak mudah untuk diotomatisasi dari baris perintah.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Terima kasih atas ikhtisar yang bagus ... Ya, "tebakan terbaik" dapat menjadi satu-satunya pilihan ketika pengkodean tidak diketahui ... Menggunakan iconv, saya hanya menjalankan semua 1.168 pengodean (termasuk alias) yang terdaftar oleh iconv -lsalah satu file .htm saya ... Ada 683 penyandian yang berhasil dihimpun .. Charset aktual file = ISO-8859-1 .. dibuat dari semua bar satu nilai kisaran ASCII .. Char non-ASCII adalah \ xA9.
Peter.O
0

Juga jika Anda mengajukan -i memberi Anda tidak dikenal

Anda dapat menggunakan perintah php ini yang dapat menebak charset seperti di bawah ini:

Di php Anda dapat memeriksa seperti di bawah ini:

Menentukan daftar penyandian secara eksplisit:

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

" Mb_list_encodings " lebih akurat :

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

Di sini, di contoh pertama, Anda dapat melihat bahwa saya meletakkan daftar penyandian (deteksi urutan daftar) yang mungkin cocok. Untuk mendapatkan hasil yang lebih akurat, Anda dapat menggunakan semua kemungkinan penyandian melalui: mb_list_encodings ()

Catatan fungsi mb_ * membutuhkan php-mbstring

apt-get install php-mbstring 

Lihat jawaban: https://stackoverflow.com/a/57010566/3382822

Mohamed23gharbi
sumber