이상한 캐릭터를 어떻게 식별 할 수 있습니까?


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않는 "진수 코드 포인트"로 , 이는 다시, 잘못된 것 같습니다 .

그럼, 어떻게 내가 세 가지 옵션 중 하나를 사용하여 (수 355, 005353또는 0aeb그들이 대표로되어있는 것을 문자 알아)?

그리고 네, 유니 코드 도구를 사용해 보았지만 유효한 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

유니 코드 U + FFFD 문자에 대한 설명을 이해하면 실제 문자가 아니며 손상된 문자의 자리 표시자가 아닙니다. 파일이 실제로 UTF-8로 인코딩되지 않았으므로 의미가 있습니다.


5
EB는 코드 페이지 437 에서 δ 이거나 코드 페이지 850 에서 Ù 이거나 8859-1 에서 in 일 수 있습니다 . 그것들 중 어떤 것이 이해가 되겠습니까? ( iconv소스 문자 세트를 지정하지 않았기 때문에 불평하므로 기본값 인 UTF-8을 사용합니다.)
Stephen Kitt

@StephenKitt 예, ë다른 프로그램에서 데이터를 사용할 때 볼 수 있습니다! 하지만 어떻게 알 수 있습니까? 내가 제공하는 데이터의 어딘가에 있지 않습니까? 어떻게 찾았 어? 아, 나는 시도했다 iconv으로 -f ISO-8859하지만 불평 conversion from supported`되지 않은 'ISO-8859.
terdon

1
아아! 나는 16 진수 표시기 또는 그 무엇이든 그냥 사용해야 eb하고 무시 해야한다는 것을 알았습니다 0x. 이런 종류의 일에 대한 나의 무지가 깊습니다. @StephenKitt를 설명하는 답변을 게시 할 수 있습니까?
terdon

5
여기서 중요한 실수는 ISO-8859가 인코딩의 이름이 아니라는 것입니다. 인코딩 제품군입니다. 분명히 찾고있는 것은 ISO-8859-1입니다.
tripleee

1
그러면 당신 iconv은 성공했을 것입니다. 및 / 또는 예를 들어 Wikipedia에서 찾아 볼 수 있습니다. 이 매우 특정한 인코딩의 경우 fileformat.info/info/unicode/char/00eb/index.htm 도 작동합니다 (유니 코드는 128-255 범위의 ISO-8859-1과 동일하지만 UTF 인코딩은 호환되지 않습니다) ).
tripleee

답변:


22

파일에는 2 바이트의 EB와 0A가 16 진수로 들어 있습니다. 파일이 ISO-8859-1 과 같이 문자 당 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 -xod -t x2한 번에 2 바이트를 읽는 맵을 작성하고 리틀 엔디안 시스템에서는 바이트를 역순으로 출력합니다.

UTF-8이 유효하지 않은 (또는 UTF-8 파일로 해석 될 때 의미가없는) 이와 같은 파일을 발견하면 자동으로 인코딩 (및 문자 세트)을 결정할 수있는 완벽한 방법이 없습니다. 컨텍스트는 도움이 될 수 있습니다. 지난 20 년 동안 Western PC에서 제작 된 파일 인 경우 ISO-8859-1, -15 (Euro 변형) 또는 Windows-1252로 인코딩 될 가능성이 높습니다. 그보다 오래된 경우 CP-437 및 CP-850이 후보가 될 수 있습니다. 동유럽 시스템, 러시아 시스템 또는 아시아 시스템의 파일은 내가 잘 모르는 다른 문자 집합을 사용합니다. 그런 다음 EBCDIC ... iconv -l가 있습니다. iconv알고있는 모든 문자 세트가 나열되며, 여기에서 시행 착오를 진행할 수 있습니다.

(한 시점에서 나는 CP-437과 ATASCII의 대부분을 마음 속으로 알고 있었기 때문에 그 시절이었다.)


1
OK, 당신이 링크 위키 피 디아 페이지에, 나는이 볼 수있는 ë것처럼 설명 00EB하고 234. 그 여분은 무엇입니까 00? 그리고 출력 355에서 예상대로 왜 그렇지 od않습니까? od출력을 사용하여 캐릭터를 식별하는 방법에 대한보다 일반적인 대답을 얻으려고합니다 . 16 진 코드 해석 및 / 또는 알 수없는 문자 (인코딩 등)를 식별하는 데 필요한 정보에 대해 설명해 주시겠습니까?
terdon

EB는 853 (355 아님)입니다. 나는 일반화하려고 노력할 것입니다 ...
Stephen Kitt

죄송합니다 353. 따라서 353은 10 진수가 아닌 8 진수 표현입니다. 아아
terdon

1
예, "o"는 od8 진수 ;-) 를 나타냅니다.
Stephen Kitt

1
어쨌든 (U + FFFD)는 UTF-8에서 유효한 문자를 형성하지 않는 0xeb 바이트를 대신하여 터미널 에뮬레이터에 의해 표시됩니다. uniprops $(cat file)따옴표 btw가 누락 된 이유를 알 수 없는 이유는 명확 하지 않습니다 (나는 그 uniprops명령 에 대해 모른다 ). unicode "$(cat file)"데비안에서 Sequence '\xeb' is not valid in charset 'UTF-8'예상대로 출력 합니다.
Stéphane Chazelas

5

od에 대한 짧은 진수 덤프 때문에, 0053538 진수 단어와 같은 2 바이트가는 od -x것입니다 0aeb단어로 진수, 그리고 파일의 실제 내용은 두 바이트 eb0a16 진수로,이 순서.

모두 그렇게 005353하고 0aeb그냥 "16 진수 코드 포인트"로 해석 할 수 없습니다.

0a줄 바꿈 (LF)이며 eb인코딩에 따라 다릅니다. file인코딩을 추측하는 것이라면 무엇이든 될 수 있습니다. 파일 등의 추가 정보가 없으면 찾기가 어려울 것입니다.


나는 이것이 코드 포인트 (또는 16 진수)가 어떻게 작동하는지 이해하지 못하기 때문에 이것을 알고 있지만 어떻게 알 수 있습니까? 나는 일반적으로 od -c이해할 수있는 출력을 생성 하기 때문에 사용 합니다. 355캐릭터를 식별하기 위해 제작 한 것을 어떻게 사용할 수 있었 습니까? 그리고 왜 인쇄하는 0aeb대신 eb0a경우 0a개행인가?
terdon

@ terdon endianness ... 내 업데이트 된 답변을 참조하십시오.
Stephen Kitt

2

텍스트 파일의 문자 집합을 100 % 정확하게 추측 할 수는 없습니다.

명시적인 charset 정보가 정의되어 있지 않은 경우 chardet , firefox , file -i 와 같은 도구 (예 : HTML에 메타 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

좋은 문자 세트 후보를 가지고 나면 iconv, recode또는 비슷한 것을 사용하여 파일 문자 세트를 "활성"문자 세트 (내 경우에는 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는 여러 chaset 정의를 포함하는 iso 표준입니다. 시도file -i ...
JJoao

1
@ terdon, 주장하여 죄송하지만, 당신이 시도한 모든 트릭은 올바른 문자 세트로 작업합니다. 예 : 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 

Instance the Word Begrung이 들어있는 파일을 얻는다면 Begrüßung이 의미하는 것으로 추론 할 수 있습니다. 그래서 나는 모든 알려진 인코더로 그것을 변환하고, 그것이 발견되었는지, 그것이 올바르게 변환되는지 봅니다.

일반적으로 여러 가지 인코딩이 있습니다.

더 긴 파일의 경우 수백 페이지를 변환하는 대신 스 니펫을자를 수 있습니다.

그래서 나는 그것을 부를 것이다

encodingfinder.sh FILE Begrüßung

스크립트는 알려진 인코딩으로 변환하여 "Begrüßung"을 생성하는지 여부를 테스트합니다.

펑키 한 캐릭터가 종종 눈에 띄기 때문에 그러한 캐릭터를 찾으려면 일반적으로 도움이되지 않습니다. 문맥에서 검색 할 올바른 단어가 일반적으로 추론 될 수 있습니다. 그러나 우리는 hexeditor를 사용하여 바이트가 무엇인지 확인한 다음 끝없는 인코딩 테이블을 방문하여 범죄자를 찾습니다. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.