วิธีตรวจหาการเข้ารหัสไฟล์ข้อความอัตโนมัติ?


69

มีไฟล์ข้อความธรรมดาจำนวนมากที่เข้ารหัสในชุดอักขระที่หลากหลาย

ฉันต้องการแปลงเป็น UTF-8 ทั้งหมด แต่ก่อนที่จะรัน iconv ฉันจำเป็นต้องรู้การเข้ารหัสดั้งเดิม เบราว์เซอร์ส่วนใหญ่มีAuto Detectตัวเลือกในการเข้ารหัสอย่างไรก็ตามฉันไม่สามารถตรวจสอบไฟล์ข้อความเหล่านี้ทีละไฟล์เพราะมีจำนวนมากเกินไป

เมื่อรู้ว่าการเข้ารหัสดั้งเดิมแล้วฉันก็สามารถแปลงข้อความiconv -f DETECTED_CHARSET -t utf-8ได้

มียูทิลิตี้ในการตรวจจับการเข้ารหัสไฟล์ข้อความธรรมดาหรือไม่? มันไม่จำเป็นต้องสมบูรณ์แบบ 100% ฉันไม่คิดว่ามีไฟล์ 100 ไฟล์ใน 1,000,000 ไฟล์ที่เข้าใจผิด

คำตอบ:


57

ลองใช้โมดูลChardet Python ซึ่งมีอยู่ใน PyPi:

pip install chardet

chardetect myfile.txtจากนั้นเรียก

Chardet ขึ้นอยู่กับรหัสตรวจจับที่ใช้โดย Mozilla ดังนั้นจึงควรให้ผลลัพธ์ที่สมเหตุสมผลโดยมีเงื่อนไขว่าข้อความที่ป้อนนั้นยาวพอสำหรับการวิเคราะห์ทางสถิติ อย่าอ่านเอกสารโครงการ

ตามที่ระบุไว้ในความคิดเห็นมันค่อนข้างช้า แต่บางส่วนยังกระจายจัดส่งต้นฉบับ c ++ รุ่น @Xavier ได้พบในhttps://superuser.com/a/609056 นอกจากนี้ยังมีรุ่น Java บางแห่ง


3
ใช่แล้วมันได้รับการบรรจุแล้วpython-chardetใน Ubuntu repo
XièJìléi

ถ้ามันไม่ได้คาดเดาที่สมบูรณ์แบบจะยังคงให้คาดเดาได้อย่างถูกต้องมากที่สุดเช่นchardet ./a.txt: GB2312 (confidence: 0.99)เปรียบเทียบกับ Enca ที่เพิ่งล้มเหลวและรายงาน 'การเข้ารหัสที่ไม่รู้จัก' อย่างไรก็ตามเศร้าพอchardetวิ่งช้ามาก
XièJìléi

1
@ 谢继雷: มันวิ่งข้ามคืนหรืออะไรทำนองนั้น การตรวจสอบ charset เป็นกระบวนการที่ซับซ้อน คุณสามารถลองใช้ jChardet ที่ใช้ Java หรือ ... chardetดั้งเดิมเป็นส่วนหนึ่งของ Mozillaแต่มีซอร์ส C ++ เท่านั้นที่พร้อมใช้งานไม่มีเครื่องมือบรรทัดคำสั่ง
grawity

2
เกี่ยวกับความเร็ว: การวิ่งchardet <(head -c4000 filename.txt)นั้นเร็วกว่าและประสบความสำเร็จเท่ากันสำหรับการใช้งานเคสของฉัน (ในกรณีที่ยังไม่ได้ล้างไวยากรณ์ทุบตีนี้จะส่งเพียง 4000 ไบต์แรกที่จะ chardet)
ndemou

@ndemou ฉันมีchardet==3.0.4และชื่อปฏิบัติการเครื่องมือบรรทัดคำสั่งที่เกิดขึ้นจริงไม่ได้chardetect chardet
Devy

32

ฉันจะใช้คำสั่งง่ายๆนี้:

encoding=$(file -bi myfile.txt)

หรือถ้าคุณต้องการเพียงชุดอักขระที่แท้จริง (เช่นutf-8):

encoding=$(file -b --mime-encoding myfile.txt)

4
ขออภัยfileตรวจพบการเข้ารหัสด้วยคุณสมบัติที่เฉพาะเจาะจงเช่น UTF-8 หรือ UTF-16 ส่วนที่เหลือ - ISO8859 ที่เก่าแก่หรือที่ติดต่อ MS-DOS และ Windows ของพวกเขานั้นถูกระบุว่าเป็น "unknown-8bit" หรือบางอย่างที่คล้ายกันแม้กระทั่งไฟล์ที่chardetตรวจจับด้วยความมั่นใจ 99%
grawity

6
ไฟล์แสดงให้ฉัน iso-8859-1
cweiske

เกิดอะไรขึ้นถ้านามสกุลกำลังโกหก
james.garriss

2
@ james.garriss: ส่วนขยายไฟล์ไม่มีส่วนเกี่ยวข้องกับการเข้ารหัสเนื้อหา (ข้อความ)
MestreLion

29

บน Linux ที่ใช้Debianแพ็คเกจuchardet ( Debian / Ubuntu ) จัดเตรียมเครื่องมือบรรทัดคำสั่ง ดูรายละเอียดแพ็คเกจด้านล่าง:

 universal charset detection library - cli utility
 .
 uchardet is a C language binding of the original C++ implementation
 of the universal charset detection library by Mozilla.
 .
 uchardet is a encoding detector library, which takes a sequence of
 bytes in an unknown character encoding without any additional
 information, and attempts to determine the encoding of the text.
 .
 The original code of universalchardet is available at
 http://lxr.mozilla.org/seamonkey/source/extensions/universalchardet
 .
 Techniques used by universalchardet are described at
 http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html

3
ขอบคุณ! จากหน้าแรกของโครงการฉันไม่เห็นชัดเจนว่ามี CLI รวมอยู่ด้วย มันยังมีอยู่ใน OS X เมื่อติดตั้งuchardetผ่าน Homebrew
Stefan Schmidt

1
ตอนแรกฉันสับสนเล็กน้อยเพราะเอกสาร ISO 8859-1 นั้นถูกระบุว่าเป็น Windows-1252 เท็จ แต่ในช่วงที่พิมพ์ได้ Windows-1252 นั้นเป็นรุ่นที่เหนือกว่าของ ISO 8859-1 ดังนั้นการแปลงด้วยการiconvทำงานที่ดี
Stefan Schmidt

16

สำหรับลินุกซ์มีencaและ Solaris คุณสามารถใช้auto_ef


Enca ดูเหมือนจะเข้มงวดเกินไปสำหรับฉัน: enca -d -L zh ./a.txtล้มเหลวด้วยข้อความ./a.txt: Unrecognized encoding Failure reason: No clear winner.ตามที่ @grawity กล่าวถึงchardetนั้นเข้มงวดมากขึ้น แต่ก็ยังช้าเกินไป
XièJìléi

10
Enca ล้มเหลวอย่างสมบูรณ์ในการทดสอบ "ทำอะไรจริง ๆ "
Michael Wolf

1
uchardet ล้มเหลว (ตรวจพบ CP1252 แทน CP1250 จริง) แต่ enca ทำงานได้ดี (ตัวอย่างเดียวยากที่จะพูดคุย ... )
Palo


2

การกลับไปที่ chardet (python 2?) การโทรนี้อาจเพียงพอ:

python -c 'import chardet,sys; print chardet.detect(sys.stdin.read())' < file
{'confidence': 0.98999999999999999, 'encoding': 'utf-8'}

แม้ว่ามันจะไกลจากความสมบูรณ์แบบ ....

echo "öasd" | iconv -t ISO-8859-1 | python -c 'import chardet,sys; print chardet.detect(sys.stdin.read())'
{'confidence': 0.5, 'encoding': 'windows-1252'}

2

สำหรับผู้ที่ใช้ Emacs เป็นประจำพวกเขาอาจพบว่ามีประโยชน์ดังต่อไปนี้ (อนุญาตให้ตรวจสอบและตรวจสอบการเปลี่ยนถ่ายด้วยตนเอง)

ยิ่งไปกว่านั้นฉันมักพบว่าการตรวจจับถ่านอัตโนมัติของ Emacs นั้นมีประสิทธิภาพมากกว่าเครื่องมือตรวจจับอัตโนมัติอื่น ๆ (เช่นชาร์ต)

(setq paths (mapcar 'file-truename '(
 "path/to/file1"
 "path/to/file2"
 "path/to/file3"
)))

(dolist (path paths)
  (find-file path)
  (set-buffer-file-coding-system 'utf-8-unix)
  )

จากนั้นการเรียก Emacs อย่างง่าย ๆ โดยใช้สคริปต์นี้เป็นอาร์กิวเมนต์ (ดูตัวเลือก "-l") ทำงาน



0

isutf8(จากmoreutilsแพ็คเกจ) ทำงานได้ดี


2
อย่างไร? คำตอบนี้ไม่เป็นประโยชน์จริงๆ
โมเสส

1
มันไม่ได้ถูกถามอย่างแน่นอน แต่เป็นเครื่องมือที่มีประโยชน์ หากไฟล์นั้นถูกต้อง UTF-8 สถานะการออกจะเป็นศูนย์ หากไฟล์นั้นไม่ถูกต้อง UTF-8 หรือมีข้อผิดพลาดบางอย่างสถานะการออกไม่เป็นศูนย์
ตัน

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.