Saya mencoba mengidentifikasi karakter aneh yang saya temukan dalam file yang saya kerjakan:
$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353 \n
0000002
$ od -x file
0000000 0aeb
0000002
File ini menggunakan penyandian ISO-8859 dan tidak dapat dikonversi ke UTF-8:
$ iconv -f ISO-8859 -t UTF-8 file
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage' for more information.
$ iconv -t UTF-8 file
iconv: illegal input sequence at position 0
$ file file
file: ISO-8859 text
Pertanyaan utama saya adalah bagaimana saya bisa menafsirkan output di od
sini? Saya mencoba menggunakan halaman ini yang memungkinkan saya menerjemahkan antara representasi karakter yang berbeda, tetapi ia memberi tahu saya bahwa 005353
sebagai "titik kode Hex" adalah 卓
yang tampaknya tidak benar dan 0aeb
sebagai "titik kode Hex" adalah ૫
yang, sekali lagi, tampaknya salah .
Jadi, bagaimana saya bisa menggunakan salah satu dari tiga opsi ( 355
, 005353
atau 0aeb
) untuk mengetahui karakter apa yang seharusnya mereka wakili?
Dan ya, saya memang mencoba dengan alat Unicode tetapi tampaknya juga bukan karakter UTF yang valid:
$ uniprops $(cat file)
U+FFFD ‹�› \N{REPLACEMENT CHARACTER}
\pS \p{So}
All Any Assigned Common Zyyy So S Gr_Base Grapheme_Base Graph X_POSIX_Graph
GrBase Other_Symbol Print X_POSIX_Print Symbol Specials Unicode
jika saya memahami deskripsi karakter Unicode U + FFFD, itu sama sekali bukan karakter asli tetapi pengganti untuk karakter yang rusak. Yang masuk akal karena file tersebut sebenarnya tidak disandikan UTF-8.
sumber
iconv
mengeluh karena Anda tidak menentukan rangkaian karakter sumber, sehingga menggunakan default Anda yang mungkin UTF-8.)ë
adalah apa yang saya lihat ketika data digunakan pada program lain! Tapi bagaimana saya bisa tahu ini? Bukankah itu di suatu tempat dalam data yang saya berikan? Bagaimana caramu menemukannya? Oh saya telah mencobaiconv
dengan-f ISO-8859
tetapi mengeluh tentangconversion from
ISO-8859' tidak supported`.eb
dan mengabaikan0x
indikator hex atau apa pun itu. Ketidaktahuan saya tentang hal semacam ini sangat mendalam. Bisakah Anda mengirim jawaban yang menjelaskan bahwa @StephenKitt?iconv
akan berhasil; dan / atau Anda bisa mencarinya misalnya di Wikipedia. Untuk pengkodean yang sangat spesifik ini, fileformat.info/info/unicode/char/00eb/index.htm juga berfungsi (Unicode setara dengan ISO-8859-1 dalam kisaran 128-255, meskipun tentu saja tidak ada pengkodean UTF yang kompatibel dengannya) ).Jawaban:
File Anda mengandung dua byte, EB dan 0A dalam hex. Kemungkinan file menggunakan set karakter dengan satu byte per karakter, seperti ISO-8859-1 ; dalam rangkaian karakter itu, EB adalah ë:
Kandidat lain akan δ di halaman kode 437 , Ù di halaman kode 850 ...
od -x
Outputnya membingungkan dalam hal ini karena endianness; pilihan yang lebih baik adalah-t x1
yang menggunakan byte tunggal:od -x
petaod -t x2
yang membaca dua byte sekaligus, dan pada sistem little-endian output byte dalam urutan terbalik.Ketika Anda menemukan file seperti ini, yang tidak valid UTF-8 (atau tidak masuk akal ketika diartikan sebagai file UTF-8), tidak ada cara bodoh untuk secara otomatis menentukan penyandian (dan set karakter). Konteks dapat membantu: jika itu adalah file yang diproduksi pada PC Barat dalam beberapa dekade terakhir, ada peluang yang wajar untuk disandikan dalam ISO-8859-1, -15 (varian Euro), atau Windows-1252; jika lebih tua dari itu, kemungkinan CP-437 dan CP-850 adalah kandidat. File dari sistem Eropa Timur, atau sistem Rusia, atau sistem Asia, akan menggunakan set karakter berbeda yang saya tidak tahu banyak tentang. Lalu ada EBCDIC ...
iconv -l
akan mendaftar semua set karakter yangiconv
tahu tentang, dan Anda dapat melanjutkan dengan coba-coba dari sana.(Pada satu titik saya tahu sebagian besar CP-437 dan ATASCII dengan hati, mereka adalah hari-hari.)
sumber
ë
digambarkan sebagai00EB
dan234
. Apa itu tambahan00
? Dan mengapa tidak355
seperti yang saya harapkan dariod
output? Saya mencoba mendapatkan jawaban yang lebih umum tentang bagaimana saya dapat menggunakanod
output untuk mengidentifikasi karakter. Bisakah Anda menjelaskan sesuatu tentang menafsirkan kode hex dan / atau informasi apa yang diperlukan untuk dapat mengidentifikasi karakter yang tidak dikenal (penyandian dan apa pun)?353
. Jadi 353 adalah representasi oktal, bukan desimal. Argh.od
singkatan oktal ;-).�
(U + FFFD) akan ditampilkan oleh terminal emulator sebagai pengganti byte 0xeb yang tidak membentuk karakter yang valid di UTF-8. Tidak jelas mengapauniprops $(cat file)
(tanda kutip yang hilang btw) akan melaporkan itu (saya tidak tahu tentanguniprops
perintah itu).unicode "$(cat file)"
pada Debian melakukan outputSequence '\xeb' is not valid in charset 'UTF-8'
seperti yang saya harapkan.Perhatikan bahwa
od
adalah singkatan sampah oktal , sehingga005353
adalah dua byte sebagai kata oktal,od -x
adalah0aeb
dalam heksadesimal sebagai kata, dan isi sebenarnya dari file Anda adalah dua byteeb
dan0a
dalam heksadesimal, dalam urutan ini.Jadi keduanya
005353
dan0aeb
tidak bisa hanya diartikan sebagai "hex code point".0a
adalah umpan baris (LF), daneb
tergantung pada pengodean Anda.file
hanya menebak pengodeannya, bisa apa saja. Tanpa informasi lebih lanjut dari mana file itu berasal dll akan sulit untuk mengetahuinya.sumber
od -c
karena itu menghasilkan output yang saya bisa mengerti. Bagaimana saya bisa menggunakan355
yang menghasilkan untuk mengidentifikasi karakter? Dan mengapa itu dicetak0aeb
bukannyaeb0a
jika0a
baris baru?Mustahil untuk menebak dengan akurasi charset file teks 100%.
Alat-alat seperti chardet , firefox , file -i ketika tidak ada informasi charset eksplisit yang didefinisikan (mis. Jika HTML berisi meta charset = ... di kepala, semuanya lebih mudah) akan mencoba menggunakan heuristik yang tidak terlalu buruk jika teksnya cukup besar.
Berikut ini, saya mendemonstrasikan deteksi charset dengan
chardet
(pip install chardet
/apt-get install python-chardet
jika perlu).Setelah memiliki calon charset yang baik, kita dapat menggunakan
iconv
,recode
atau mirip untuk mengubah charset file ke charset "aktif" Anda (dalam kasus saya utf-8) dan melihat apakah itu menebak dengan benar ...Beberapa charset (seperti iso-8859-3, iso-8859-1) memiliki banyak kesamaan - terkadang tidak mudah untuk melihat apakah kita menemukan charset yang sempurna ...
Jadi, sangat penting untuk memiliki metadata yang terkait dengan teks yang relevan (mis. XML).
sumber
iconv -f ... -t utf-8
akan menunjukkan karakternya?iso-8850-1
. iso-8859 adalah standar iso yang mencakup beberapa definisi chaset. Cobafile -i ...
iconv -f ISO-8859-1 -t UTF-8 file
Jika saya mendapatkan file, yang berisi, untuk Instance the Word Begrung, saya dapat menyimpulkan bahwa Begrüßung mungkin dimaksudkan. Jadi saya mengonversinya dengan semua encodindgs yang dikenal dan lihat, apakah ada yang ditemukan, yang mengubahnya dengan benar.
Biasanya, ada beberapa pengkodean yang tampaknya cocok.
Untuk file yang lebih panjang, Anda dapat memotong cuplikan alih-alih mengonversi ratusan halaman.
Jadi saya akan menyebutnya
dan tes skrip, apakah dengan mengubahnya dengan pengkodean yang dikenal, yang mana dari mereka menghasilkan "Begrüßung".
Untuk menemukan karakter seperti itu, biasanya kurang membantu, karena karakter yang funky sering menonjol. Dari konteksnya, kata yang tepat untuk dicari biasanya dapat disimpulkan. Tapi kami tidak ingin memeriksa dengan hexeditor, byte apa ini, dan kemudian mengunjungi tabel pengkodean tak berujung, untuk menemukan pelaku kami. :)
sumber