ฉันจะระบุตัวละครที่แปลกได้อย่างไร


10

ฉันพยายามระบุตัวละครแปลก ๆ ที่ฉันพบในไฟล์ที่ฉันทำงานด้วย:

$ cat file
�
$ od file
0000000 005353
0000002
$ od -c file
0000000 353  \n
0000002
$ od -x file
0000000 0aeb
0000002

ไฟล์กำลังใช้การเข้ารหัส ISO-8859 และไม่สามารถแปลงเป็น 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

คำถามหลักของฉันคือฉันจะตีความผลลัพธ์ของodที่นี่ได้อย่างไร ฉันพยายามใช้หน้านี้ซึ่งช่วยให้ฉันแปลระหว่างการแสดงตัวอักษรที่แตกต่างกัน แต่มันบอกฉันว่า005353"จุด Hex code" นั้นดูไม่ถูกต้องและ0aebเป็น "Hex code point" ซึ่งดูเหมือนว่าผิด .

ดังนั้นวิธีการที่ฉันสามารถใช้ใด ๆ ของสามตัวเลือก ( 355, 005353หรือ0aeb) เพื่อหาสิ่งที่ตัวละครที่พวกเขาควรจะเป็นตัวแทน?

และใช่ฉันลองใช้เครื่องมือ Unicode แต่ดูเหมือนจะไม่เป็นอักขระ UTF ที่ถูกต้องเช่นกัน:

$ 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

ถ้าฉันเข้าใจคำอธิบายของอักขระ Unicode U + FFFD มันไม่ใช่ตัวจริง แต่เป็นตัวยึดสำหรับอักขระที่เสียหาย ซึ่งเหมาะสมแล้วเนื่องจากไฟล์ไม่ได้เข้ารหัส UTF-8


5
EB อาจจะδในหน้ารหัส 437หรือÙในหน้ารหัส 850หรืออีใน8859-1 ; สิ่งเหล่านี้จะสมเหตุสมผลไหม? ( iconvบ่นเพราะคุณไม่ได้ระบุชุดอักขระต้นฉบับดังนั้นจึงใช้ค่าเริ่มต้นของคุณซึ่งอาจเป็น UTF-8)
Stephen Kitt

@StephenKitt ใช่ëเป็นสิ่งที่ฉันเห็นเมื่อมีการใช้ข้อมูลในโปรแกรมอื่น! แต่ฉันจะรู้ได้อย่างไร มันไม่ได้อยู่ในข้อมูลที่ฉันให้หรือเปล่า คุณค้นพบมันได้อย่างไร โอ้ฉันได้พยายามiconvด้วย-f ISO-8859แต่ก็บ่นเรื่องconversion from ISO-8859' ไม่ได้ supported`
terdon

1
โอ๊ะ! ฉันเห็นฉันต้องการใช้เพียงebและไม่สนใจ0xตัวบ่งชี้ฐานสิบหกหรืออะไรก็ตามที่เป็น ความไม่รู้ของฉันเกี่ยวกับเรื่องแบบนี้ลึก คุณสามารถโพสต์คำตอบที่อธิบายว่า @StephenKitt ได้หรือไม่
terdon

5
ความผิดพลาดที่สำคัญของคุณคือ ISO-8859 ไม่ใช่ชื่อของการเข้ารหัส มันเป็นตระกูลการเข้ารหัส เห็นได้ชัดว่าสิ่งที่คุณกำลังมองหาคือ ISO-8859-1
tripleee

1
จากนั้นคุณiconvก็จะประสบความสำเร็จ; และ / หรือคุณสามารถค้นหาได้เช่นใน Wikipedia สำหรับการเข้ารหัสที่เฉพาะเจาะจงนี้fileformat.info/info/unicode/char/00eb/index.htmก็ใช้งานได้ (Unicode เทียบเท่ากับ ISO-8859-1 ในช่วง 128-255 ถึงแม้ว่าแน่นอนว่าการเข้ารหัส UTF ไม่สามารถทำงานร่วมกับมันได้ )
tripleee

คำตอบ:


22

ไฟล์ของคุณมีสองไบต์, EB และ 0A เป็นเลขฐานสิบหก เป็นไปได้ว่าไฟล์จะใช้ชุดตัวอักษรที่มีหนึ่งไบต์ต่อตัวอักษรเช่นISO-8859-1 ; ในชุดอักขระนั้น EB คือë:

$ printf "\353\n" | iconv -f ISO-8859-1
ë

ผู้สมัครคนอื่น ๆ จะเป็นδในหน้ารหัส 437 , ในหน้ารหัส 850 ...

od -xผลลัพธ์ในกรณีนี้เกิดความสับสนเนื่องจากความเป็น endianness ตัวเลือกที่ดีกว่าคือการ-t x1ใช้ไบต์เดียว:

$ printf "\353\n" | od -t x1
0000000 eb 0a
0000002

od -xแม็พod -t x2ที่อ่านสองไบต์ในแต่ละครั้งและในระบบเล็ก ๆ น้อย ๆ ส่งเอาต์พุตไบต์ในลำดับย้อนกลับ

เมื่อคุณเจอไฟล์แบบนี้ซึ่งไม่ถูกต้อง UTF-8 (หรือไม่มีเหตุผลเมื่อตีความว่าเป็นไฟล์ UTF-8) ไม่มีวิธีที่จะพิสูจน์การเข้ารหัสโดยอัตโนมัติ (และชุดอักขระ) ได้ บริบทสามารถช่วย: ถ้าเป็นไฟล์ที่สร้างจากพีซีแบบตะวันตกในช่วงสองสามทศวรรษที่ผ่านมามีโอกาสที่จะถูกเข้ารหัสใน ISO-8859-1, -15 (ตัวแปรยูโร) หรือ Windows-1252; หากมีอายุมากกว่านั้น CP-437 และ CP-850 ก็น่าจะเป็นผู้สมัคร ไฟล์จากระบบยุโรปตะวันออกหรือระบบรัสเซียหรือระบบเอเชียจะใช้ชุดอักขระที่แตกต่างกันซึ่งฉันไม่รู้มาก จากนั้นก็มี EBCDIC ... iconv -lจะแสดงชุดตัวละครทั้งหมดที่iconvรู้และคุณสามารถดำเนินการต่อโดยการลองผิดลองถูก

(จนถึงจุดหนึ่งฉันรู้ว่า CP-437 และ ATASCII ส่วนใหญ่ปิดด้วยหัวใจพวกเขาคือวันนั้น)


1
ตกลงในหน้าวิกิพีเดียคุณเชื่อมโยงไปผมจะเห็นว่าëคำอธิบายที่เป็นและ00EB 234สิ่งที่พิเศษเหล่านั้น00คืออะไร? และทำไมมันไม่355เป็นอย่างที่ฉันคาดหวังจากodเอาท์พุท? ฉันกำลังพยายามหาคำตอบทั่วไปเพิ่มเติมเกี่ยวกับวิธีใช้odเอาต์พุตเพื่อระบุอักขระ คุณอาจอธิบายบางอย่างเกี่ยวกับการแปลรหัสฐานสิบหกและ / หรือข้อมูลใดบ้างที่จำเป็นเพื่อระบุอักขระที่ไม่รู้จัก (การเข้ารหัสและสิ่งอื่นใด)
terdon

EB คือ 353 ในหน่วยแปด (ไม่ใช่ 355) ฉันจะพยายามพูดคุยกัน ...
สตีเฟ่น Kitt

353อ๊ะขอโทษฉันหมายถึง 353 จึงเป็นการแทนฐานแปดไม่ใช่ทศนิยม โอ๊ะ
terdon

1
ใช่เครื่องหมาย“ o” odย่อมาจาก octal ;-)
Stephen Kitt

1
ไม่ว่าในกรณีใดเทอร์มินัลอีมูเลเตอร์ (U + FFFD) จะแสดงแทน 0xeb ไบต์ที่ไม่มีอักขระที่ถูกต้องใน UTF-8 มันไม่ชัดเจนว่าทำไมuniprops $(cat file)(อัญประกาศ btw ที่หายไป) จะรายงานว่า (ฉันไม่รู้เกี่ยวกับunipropsคำสั่งนั้น) unicode "$(cat file)"บนเดเบียนทำออกSequence '\xeb' is not valid in charset 'UTF-8'ตามที่ฉันคาดหวัง
Stéphane Chazelas

5

โปรดทราบว่าodสั้นสำหรับการถ่ายโอนฐานแปดดังนั้น005353สองไบต์เป็นคำฐานแปดod -xอยู่0aebในเลขฐานสิบหกเป็นคำและเนื้อหาที่แท้จริงของไฟล์ของคุณคือสองไบต์ebและ0aเลขฐานสิบหกตามลำดับนี้

ดังนั้นทั้งสอง005353และ0aebไม่สามารถตีความได้ว่าเป็น "รหัสเลขฐานสิบหก"

0aเป็นตัวป้อนบรรทัด (LF) และebขึ้นอยู่กับการเข้ารหัสของคุณ fileเพียงแค่เดาการเข้ารหัสมันอาจเป็นอะไรก็ได้ หากไม่มีข้อมูลเพิ่มเติมใด ๆ ที่ไฟล์มาจาก ฯลฯ มันจะยากที่จะค้นหา


ฉันรู้ว่านี่เป็นเพราะฉันไม่เข้าใจว่าจุดรหัส (หรือฐานสิบหก) ทำงานอย่างไร แต่ฉันจะรู้ได้อย่างไร ฉันมักจะใช้od -cตั้งแต่ที่ผลิตออกมาฉันสามารถเข้าใจ ฉันจะใช้สิ่ง355ที่สร้างขึ้นเพื่อระบุตัวละครได้อย่างไร และทำไมมันพิมพ์0aebแทนeb0aถ้า0aเป็นบรรทัดใหม่หรือไม่?
terdon

@terdon endianness ... ดูคำตอบที่อัปเดตของฉัน
Stephen Kitt

2

มันเป็นไปไม่ได้ที่จะคาดเดาด้วยความแม่นยำ 100% ของชุดอักขระของไฟล์ข้อความ

เครื่องมือเช่นchardet , firefox , file -iเมื่อไม่มีการกำหนดข้อมูล charset อย่างชัดเจน (เช่นหาก HTML มี meta charset = ... ในหัวสิ่งต่าง ๆ จะง่ายกว่า) จะพยายามใช้การวิเคราะห์พฤติกรรมที่ไม่เลวถ้า ข้อความมีขนาดใหญ่พอ

ในต่อไปนี้ฉันสาธิตการตรวจจับชุดอักขระด้วยchardet( pip install chardet/ apt-get install python-chardetหากจำเป็น)

$ echo "in Noël" | iconv -f utf8 -t latin1  | chardet
<stdin>: windows-1252 with confidence 0.73

หลังจากที่มีผู้สมัครที่ดี charset เราสามารถใช้iconv, recodeหรือคล้ายกันที่จะเปลี่ยน charset ไฟล์ที่คุณ "ใช้งาน" charset (UTF-8 กรณีของฉัน) และดูว่ามันถูกต้องเดา ...

iconv -f windows-1252  -t utf-8 file

ชุดอักขระบางอย่าง (เช่น iso-8859-3, iso-8859-1) มีตัวอักษรจำนวนมากเหมือนกัน - บางครั้งมันก็ไม่ง่ายที่จะดูว่าเราพบชุดที่สมบูรณ์แบบ ...

ดังนั้นจึงเป็นเรื่องสำคัญมากที่จะต้องมีข้อมูลเมตาที่เชื่อมโยงกับข้อความที่เกี่ยวข้อง (เช่น XML)


อืมมม ฉันทำซ้ำไม่ได้ที่นี่มันแค่ล่ม แต่ในกรณีใด ๆ นั่นไม่ได้เป็นการบอกให้ฉันเข้ารหัสไฟล์เลยเหรอ? ปัญหาของฉันคือการระบุตัวละครไม่ใช่การเข้ารหัสไฟล์ ที่ฉันรู้แล้ว
terdon

1
ขออภัยฉันไม่เข้าใจคำถาม (ปัญหาปกติของฉันคือการระบุชุดอักขระ) ถ้าคุณเข้ารหัสตอนนี้iconv -f ... -t utf-8 จะแสดงตัวอักษร?
JJoao

ไม่ฉันแสดงการเข้ารหัสตรงนั้น มีอักขระหนึ่งตัวที่ไม่รองรับการเข้ารหัสนั้นและเป็นอักขระที่ฉันพยายามระบุ
terdon

1
Iso-8859 ไม่ใช่การเข้ารหัส! iso-8850-1การเข้ารหัสเป็น iso-8859 เป็น iso มาตรฐานรวมถึงคำจำกัดความ chaset หลาย ลองfile -i ...
JJoao

1
@terdon ขอโทษที่ยืนยัน แต่เล่ห์เหลี่ยมทั้งหมดที่คุณพยายามทำงานกับชุดอักขระที่เหมาะสม Ex: iconv -f ISO-8859-1 -t UTF-8 file
JJoao

0
#!/bin/bash
#
# Search in a file, a known (part of a ) String (i.E.: Begrüßung),
# by testing all encodings
#
[[ $# -ne 2 ]] && echo "Usage: encoding-finder.sh FILE fUnKy_CHAR_FOR_SURE_IN_FILE" && exit
FILE=$1
PATTERN=$2
for enc in $( iconv -l | sed 's/..$//') 
do 
    iconv -f $enc -t UTF-8 $FILE  2>/dev/null | grep -m 1 $PATTERN && echo $enc 
done 

หากฉันได้รับไฟล์ซึ่งมีไว้สำหรับอินสแตนซ์ Word Begrung ฉันสามารถอนุมานได้ว่าBegrüßungอาจมีความหมาย ดังนั้นฉันจึงแปลงมันโดย encodindgs ที่รู้จักกันทั้งหมดและดูว่ามีใครพบซึ่งแปลงมันอย่างเหมาะสม

โดยปกติจะมีการเข้ารหัสหลายรายการซึ่งดูเหมือนจะพอดี

สำหรับไฟล์ที่ยาวกว่านี้คุณอาจตัดส่วนย่อยแทนที่จะแปลงหลายร้อยหน้า

ดังนั้นฉันจะเรียกมันว่า

encodingfinder.sh FILE Begrüßung

และบททดสอบไม่ว่าจะเป็นการแปลงด้วยการเข้ารหัสที่รู้จักซึ่งพวกเขาสร้าง "Begrüßung"

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

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