Saya punya beberapa .htm
file yang terbuka Gedit tanpa peringatan/kesalahan, tetapi ketika saya membuka file yang sama di Jedit
, ia memperingatkan saya tentang pengkodean UTF-8 yang tidak valid ...
Tag meta HTML menyatakan "charset = ISO-8859-1". Jedit memungkinkan Daftar penyandian fallback dan Daftar pendeteksi pendeteksi otomatis (saat ini "BOM XML-PI"), jadi masalah langsung saya telah diatasi. 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 itu masalah yang sedikit berbeda; apakah ada program CLI yang menguji validitas dari dikenal pengkodean?
Perintah file
membuat "tebakan terbaik" tentang penyandian. Menggunakan -i
parameter untuk memaksa file
untuk mencetak 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 file
katakan:
$ 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
Perintah file
tidak tahu "valid" atau "tidak valid". 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 dari file
adalah semacam kecerdasan buatan. Namun, bahkan jika itu, itu sangat terbatas.
Berikut ini informasi lebih lanjut tentang perintah file
: http://www.linfo.org/file_command.html
Tidak selalu mungkin untuk mengetahui dengan pasti apa penyandian file teks. Misalnya, urutan byte \303\275
(c3 bd
dalam heksadesimal) bisa ý
dalam UTF-8, atau ý
dalam bahasa latin1, atau Ă˝
dalam bahasa 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 isutf8
from moreutils atau dengan iconv -f utf-8 -t utf-8 >/dev/null
, di antara yang 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
Encode::Guess
(bagian dari distribusi standar) mencoba penyandian berurutan pada string byte dan mengembalikan penyandian pertama di mana string adalah teks yang valid.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.
Juga jika Anda mengajukan -i memberi Anda tidak diketahui
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;"
Lebih akurat " mb_list_encodings ":
php -r "echo 'probably : ' . mb_detect_encoding(file_get_contents('myfile.txt'), mb_list_encodings()) . PHP_EOL;"
Di sini, dalam 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