奇妙なキャラクターを特定するにはどうすればよいですか?


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、「16進コードポイント」は正しくないように見え0aeb、「16進コードポイント」はまた間違っているようです。 。

では、3つのオプション(355005353または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ではbe 、8859-1ではbeになります。それらのいずれかが理にかなっていますか?(iconvソース文字セットを指定しなかったため文句を言うので、おそらくUTF-8であるデフォルトを使用します。)
Stephen Kitt

@StephenKittはい、ëデータが別のプログラムで使用されるときに私が見るものです!しかし、どうすればこれを知ることができますか?私が提供するデータのどこかにありませんか?どうやって分かったの?ああ、試してみiconvました-f ISO-8859が、conversion from ISO-8859 'はサポートされていません。
terdon

1
ああ!なるほど、私はちょうど16進数のインジケーターか何かをeb無視して無視する必要0xがあった。このようなことに対する私の無知は深い。@StephenKittを説明する回答を投稿していただけませんか?
terdon

5
ここでの重大な間違いは、ISO-8859がエンコーディングの名前ではないということです。これはエンコーディングのファミリです。明らかに、探しているのはISO-8859-1です。
tripleee 2017

1
その後、あなたiconvは成功したでしょう。ウィキペディアなどで調べた可能性があります。この非常に特殊なエンコーディングでは、fileformat.info / info / unicode / char / 00eb / index.htmも機能します(Unicodeは、128-255の範囲でISO-8859-1と同等ですが、もちろん、UTFエンコーディングとは互換性がありません。 )。
tripleee 2017

回答:


22

ファイルには、EBと0Aの2バイトが16進数で含まれています。ファイルがISO-8859-1などの文字ごとに1バイトの文字セットを使用している可能性があります。その文字セットでは、EBはëです。

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

他の候補は、コードページ437の δ 、コードページ850の ...などです。

od -xこの場合、エンディアンのため、の出力は混乱します。より良いオプションは-t x1シングルバイトを使用することです:

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

od -xod -t x2は一度に2バイトを読み取るマップで、リトルエンディアンシステムではバイトを逆の順序で出力します。

このような、有効なUTF-8ではない(またはUTF-8ファイルとして解釈されても意味がない)ファイルに遭遇した場合、そのエンコーディング(および文字セット)を自動的に決定するための確実な方法はありません。コンテキストが役立ちます。過去20年間に西洋PCで作成されたファイルの場合、ISO-8859-1、-15(ユーロバリアント)、またはWindows-1252でエンコードされている可能性がかなりあります。それより古い場合は、CP-437とCP-850がおそらく候補です。東ヨーロッパのシステム、またはロシアのシステム、またはアジアのシステムのファイルは、私がよく知らない別の文字セットを使用します。次に、EBCDICがあります... iconv -lは、iconv認識しているすべての文字セットをリストし、そこから試行錯誤することができます。

(ある時点で、私はCP-437とATASCIIのほとんどを暗記していました。それらは当時のことでした。)


1
OK、あなたがにリンクWikipediaのページに、私は見ることができるëと記載されている00EB234。それらの余分なものは何00ですか?そして、なぜ出力355から期待したとおりではないのodですか?od文字を識別するために出力を使用する方法について、より一般的な答えを得ようとしています。16進コードの解釈について何か説明したり、不明な文字(エンコーディングなど)を特定するために必要な情報を教えてください。
terdon

EBは8進数で353です(355ではありません)。私は一般化しようとします...
スティーブンキット

おっと、すみません、私は意味しました353。したがって、353は10進数ではなく、8進数表現です。ああ。
terdon

1
はい、「o」はod8進数を表します;-)。
Stephen Kitt 2017

1
いずれの場合も、(U + FFFD)は、UTF-8で有効な文字を形成しない0xebバイトの代わりとして、端末エミュレーターによって表示されます。uniprops $(cat file)(引用符がない)がそれを報告する理由は明確ではありません(そのunipropsコマンドについては知りません)。unicode "$(cat file)"DebianではSequence '\xeb' is not valid in charset 'UTF-8'期待どおりに出力します。
ステファンChazelas

5

odのために短い進ダンプは、そう005353進語などの2バイトであり、od -xある0aeb単語として進数で、そしてあなたのファイルの実際の内容は2つのバイトeb0a、この順で、16進数で指定できます。

両方そう0053530aebばかり「進コード・ポイント」として解釈することはできません。

0a改行(LF)でありeb、エンコードに依存します。fileエンコーディングを推測するだけで、何でもかまいません。ファイルの出所などの詳細情報がないと、見つけるのが困難になります。


これは、コードポイント(実際には16進数)のしくみがわからないためだと思いますが、どうすればわかりますか?私は通常使用しod -cているが、私は理解することができ、出力を生成するので。355生成されたを使用してキャラクターを識別するにはどうすればよいですか?そして、なぜそれが印刷される0aeb代わりのeb0a場合は0a、改行がありますか?
terdon

@terdon endianness ...私の最新の答えを見てください。
Stephen Kitt 2017

2

テキストファイルの文字セットを100%正確に推測することは不可能です。

chardetfirefoxfile -iなどのツールは、明示的な文字セット情報が定義されていない場合(たとえば、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

適切な文字セットの候補を取得したらiconvrecodeなどを使用して、ファイルの文字セットを「アクティブ」な文字セット(私の場合は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 2017

いいえ、ここにエンコードを表示します。そのエンコーディングでサポートされていない特定の文字が1つあり、それは私が識別しようとしていた文字です。
terdon

1
ISO-8859はエンコーディングではありません!エンコーディングはiso-8850-1です。iso-8859は、いくつかのシャセット定義を含むiso標準です。試してみてくださいfile -i ...
JJoao

1
@terdon、主張して​​申し訳ありませんが、あなたが試したすべてのトリックは正しい文字セットで動作しました。例: iconv -f ISO-8859-1 -t UTF-8 file
JJoao 2017

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 

たとえば、Begrungという単語が含まれているファイルを取得した場合、Begrüßungが意図されていると推測できます。それで、私はそれをすべての既知のencodindgsで変換し、見つかるかどうかを調べて、正しく変換します。

通常、適合するように見える複数のエンコーディングがあります。

長いファイルの場合は、数百ページを変換する代わりにスニペットをカットする場合があります。

だから私はそれを呼びます

encodingfinder.sh FILE Begrüßung

また、スクリプトテストでは、既知のエンコーディングで変換するかどうかに関係なく、「Begrüßung」を生成します。

ファンキーなキャラクターが目立つことが多いため、このようなキャラクターを見つけるには、通常はあまり役に立ちません。文脈から、通常、検索する適切な単語を推測できます。しかし、私たちはhexeditorでこれが何バイトであるかをチェックしたくないので、エンコーディングのエンドレステーブルにアクセスして、攻撃者を見つけます。:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.