ฉันจะทดสอบการเข้ารหัสไฟล์ข้อความได้อย่างไร ... มันถูกต้องและมันคืออะไร?


46

ฉันมี.htmไฟล์หลายไฟล์ที่เปิดในGeditโดยไม่มีการเตือน / ข้อผิดพลาดใด ๆ แต่เมื่อฉันเปิดไฟล์เดียวกันนี้Jeditมันจะเตือนฉันเกี่ยวกับการเข้ารหัส UTF-8 ที่ไม่ถูกต้อง ...

แท็ก meta ของ HTML ระบุว่า "charset = ISO-8859-1" Jedit อนุญาตให้ใช้รายการการเข้ารหัสทางเลือกและรายการการเข้ารหัสเครื่องตรวจจับอัตโนมัติ (ปัจจุบันคือ "BOM XML-PI") ดังนั้นปัญหาในทันทีของฉันจึงได้รับการแก้ไข แต่นี่ทำให้ฉันคิดถึง: จะเกิดอะไรขึ้นถ้าข้อมูลเมตาไม่อยู่ที่นั่น?

เมื่อข้อมูลการเข้ารหัสไม่สามารถใช้งานได้มีโปรแกรม CLI ที่สามารถ "เดาได้ดีที่สุด" ซึ่งการเข้ารหัสอาจใช้หรือไม่

และถึงแม้ว่ามันจะเป็นปัญหาที่แตกต่างออกไปเล็กน้อย มีโปรแกรม CLI ซึ่งทดสอบความถูกต้องของการเข้ารหัสที่รู้จักหรือไม่


คล้ายกับ "วิธีตรวจหาการเข้ารหัสไฟล์ข้อความอัตโนมัติ" superuser.com/questions/301552/…
buzz3791

คำตอบ:


60

fileคำสั่งทำให้ "ดีที่สุดคาดเดา" เกี่ยวกับการเข้ารหัส ใช้-iพารามิเตอร์เพื่อบังคับfileให้พิมพ์ข้อมูลเกี่ยวกับการเข้ารหัส

สาธิต:

$ 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

นี่คือวิธีที่ฉันสร้างไฟล์:

$ echo ä > umlaut-utf8.txt 

ทุกอย่างในปัจจุบันคือ utf-8 แต่โน้มน้าวตัวเอง:

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

เปรียบเทียบกับhttps://en.wikipedia.org/wiki/Ä#Computer_encoding

เปลี่ยนเป็นการเข้ารหัสอื่น ๆ :

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

ตรวจสอบดัมพ์หกเหลี่ยม:

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

สร้างบางอย่าง "ไม่ถูกต้อง" โดยผสมทั้งสามอย่าง:

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

fileพูดว่าอะไร:

$ 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

ไม่มี-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

fileคำสั่งมีความคิดไม่ "ถูกต้อง" หรือ "ไม่ถูกต้อง" มันเพิ่งเห็นไบต์และพยายามเดาว่าการเข้ารหัสอาจเป็นอะไร ในฐานะมนุษย์เราอาจสามารถรับรู้ได้ว่าไฟล์เป็นไฟล์ข้อความที่มีเครื่องหมายบางอันในการเข้ารหัส "ผิด" แต่ในฐานะคอมพิวเตอร์มันต้องมีปัญญาประดิษฐ์บางอย่าง

บางคนอาจแย้งว่าฮิวริสติกfileของปัญญาประดิษฐ์ ถึงแม้ว่ามันจะเป็นแบบ จำกัด ก็ตาม

นี่คือข้อมูลเพิ่มเติมเกี่ยวกับfileคำสั่ง: http://www.linfo.org/file_command.html


ขอบคุณที่ทำงาน ... ฉันได้พยายาม 'ไฟล์, but without any option :( ... I've now also tried a mixof UTF-16 and UTF-8 and ISO-8859-1. ไฟล์ -i` unknown-8bitรายงาน ดังนั้นนี่ก็เป็นคำตอบสำหรับ: "วิธีการตรวจจับการเข้ารหัสที่ไม่ถูกต้อง / ไม่รู้จัก"
Peter.O

สำหรับผู้ที่มาที่นี่และอยู่บน mac file -Iด้วยทุน 'i' แทนที่จะเป็นตัวพิมพ์เล็ก
samuraiseoul

21

มันเป็นไปไม่ได้เสมอที่จะทราบว่าการเข้ารหัสของไฟล์ข้อความคืออะไร ตัวอย่างเช่นลำดับไบต์\303\275(เป็นc3 bdเลขฐานสิบหก) อาจเป็นýUTF-8 หรือýใน latin1 หรือĂ˝ใน latin2 หรือใน BIG-5 และอื่น ๆ

การเข้ารหัสบางตัวมีลำดับไบต์ที่ไม่ถูกต้องดังนั้นจึงเป็นไปได้ที่จะตัดการเชื่อมต่อออกอย่างแน่นอน นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่ง UTF-8 ข้อความส่วนใหญ่ในการเข้ารหัส 8 บิตส่วนใหญ่ไม่ถูกต้อง UTF-8 คุณสามารถทดสอบ UTF-8 ที่ถูกต้องได้isutf8จากหลายรายการหรือiconv -f utf-8 -t utf-8 >/dev/nullมากกว่า

มีเครื่องมือที่พยายามเดาการเข้ารหัสไฟล์ข้อความ พวกเขาสามารถทำผิดพลาดได้ แต่พวกเขามักจะฝึกซ้อมตราบใดที่คุณไม่ได้พยายามหลอกพวกเขา

  • file
  • PerlEncode::Guess (ส่วนหนึ่งของการแจกแจงมาตรฐาน) พยายามเข้ารหัสต่อเนื่องในสตริงไบต์และส่งกลับการเข้ารหัสครั้งแรกที่สตริงเป็นข้อความที่ถูกต้อง
  • Encaเป็นตัวเดาการเข้ารหัสและตัวแปลง คุณสามารถตั้งชื่อภาษาและข้อความที่คุณเข้าใจว่าเป็นภาษานั้น (ภาษาที่รองรับส่วนใหญ่เป็นภาษายุโรปตะวันออก) และพยายามคาดเดาการเข้ารหัส

หากมีข้อมูลเมตา (HTML / XML charset=, TeX \inputenc, emacs -*-coding-*-, …) ในไฟล์บรรณาธิการขั้นสูงเช่น Emacs หรือ Vim มักจะสามารถแยกวิเคราะห์ข้อมูลเมตานั้นได้ นั่นไม่ใช่เรื่องง่ายที่จะทำให้เป็นอัตโนมัติจากบรรทัดคำสั่ง


ขอบคุณสำหรับภาพรวมที่ดี ... ใช่ "best-guess" สามารถเป็นตัวเลือกเดียวเมื่อไม่รู้จักการเข้ารหัส ... การใช้iconvฉันใช้การเข้ารหัส 1168 ทั้งหมด (รวมถึงนามแฝง) ที่ระบุโดยiconv -lไฟล์. htm ของฉัน ... มีการเข้ารหัส 683 รายการที่ผ่านการรวบรวม .. ชุดอักขระที่แท้จริงของไฟล์ = ISO-8859-1 .. สร้างขึ้นจากแถบทั้งหมดหนึ่งช่วงค่า ASCII .. ถ่านที่ไม่ใช่ ASCII คือ \ xA9
Peter.O

0

นอกจากนี้ในกรณีที่คุณไฟล์ -i ให้คุณไม่ทราบ

คุณสามารถใช้คำสั่ง php นี้ซึ่งสามารถเดาชุดอักขระตามด้านล่าง:

ใน php คุณสามารถตรวจสอบได้ดังนี้:

การระบุรายการเข้ารหัสอย่างชัดเจน:

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 " ที่แม่นยำยิ่งขึ้น :

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

ในตัวอย่างแรกคุณจะเห็นว่าฉันใส่รายการการเข้ารหัส (ตรวจจับลำดับรายการ) ที่อาจจับคู่ หากต้องการผลลัพธ์ที่แม่นยำยิ่งขึ้นคุณสามารถใช้การเข้ารหัสที่เป็นไปได้ทั้งหมดผ่าน: mb_list_encodings ()

หมายเหตุ mb_ * ฟังก์ชั่นต้องการ php-mbstring

apt-get install php-mbstring 

ดูคำตอบ: https://stackoverflow.com/a/57010566/3382822

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.