2008-09-22 11 views
51

유효한 UTF-8이 아닌 일부 데이터 파일을 처리하고 있는데, 파서 (내 제어 권한이 아님)가 실패하게됩니다. UTF-8 형식화에 대한 데이터를 사전 검증하는 단계를 추가하고 싶지만 아직이 작업을 수행하는 데 유용한 유틸리티를 찾지 못했습니다.파일이 유효한 UTF-8인지 확인하는 방법은 무엇입니까?

W3C에 죽은 것으로 보이는 web service이 있는데 올바르지 않은 UTF-8 파일을보고하지만 수정할 줄/문자를보고하지 않는 Windows 전용 유효성 검사 tool을 발견했습니다.

내가 떨어 뜨릴 수있는 도구 (이상적으로는 크로스 플랫폼) 또는 루비/펄 스크립트를 사용하여 데이터로드 프로세스에 참여할 수있어서 행복 할 것입니다.

답변

72

당신은 GNU의의 iconv를 사용할 수 있습니다

$ iconv -f UTF-8 your_file -o /dev/null 

또는 맥 OS에로의 iconv 이전 버전과

:

파일을 성공적으로 변환 할 수 있다면이 명령은 0을 반환합니다
$ iconv -f UTF-8 your_file > /dev/null; echo $? 

하고, 그렇지 않다면 1입니다. 또한 잘못된 바이트 시퀀스가 ​​발생한 바이트 오프셋을 인쇄합니다.

편집 : 출력 인코딩을 지정하지 않아도됩니다. 출력 인코딩은 UTF-8로 간주됩니다.

+13

OSX 나 fink의 이전 버전의 iconv에는 -o 플래그가 없습니다. 그러나 stdout을 리디렉션하면 항상 작동해야합니다. –

+1

Torsten, 고마워, 내 리눅스 머신에서 완벽하게 작동한다. cygwin 용 iconv 유틸리티의 버전을 찾을 수 없지만, 그것은 showstopper가 아닙니다. –

+2

모든 문제를 포착하지 못했습니다 ... – zvolkov

10

python 및 str.encode | decode 함수를 사용하십시오.

>>> a="γεια" 
>>> a 
'\xce\xb3\xce\xb5\xce\xb9\xce\xb1' 
>>> b='\xce\xb3\xce\xb5\xce\xb9\xff\xb1' # note second-to-last char changed 
>>> print b.decode("utf_8") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/local/lib/python2.5/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 6: unexpected code byte 

예외는 .args 속성에서 요청 된 정보를 갖습니다.

>>> try: print b.decode("utf_8") 
... except UnicodeDecodeError, exc: pass 
... 
>>> exc 
UnicodeDecodeError('utf8', '\xce\xb3\xce\xb5\xce\xb9\xff\xb1', 6, 7, 'unexpected code byte') 
>>> exc.args 
('utf8', '\xce\xb3\xce\xb5\xce\xb9\xff\xb1', 6, 7, 'unexpected code byte') 
3

gnu iconv 라이브러리는 어떻습니까? iconv() 함수 사용 : "입력에 유효하지 않은 멀티 바이트 시퀀스가 ​​발생했습니다.이 경우 errno를 EILSEQ로 설정하고 (size_t) (- 1)을 반환합니다. * inbuf는 잘못된 멀티 바이트 시퀀스의 시작 부분을 가리 킵니다. "

편집 : 오 - 내가 스크립트 언어를 원하는 부분을 놓쳤습니다. 그러나 명령 행 작업의 경우 iconv 유틸리티가 사용자를 확인해야합니다.

-3

아래의 C++ 코드는 인터넷을 통해 많은 사이트에 게시 된 코드를 기반으로합니다. 원래 코드에서 오류를 수정하고 잘못된 문자와 잘못된 문자 자체의 위치를 ​​모두 검색 할 수있는 가능성을 추가했습니다.

///Returns -1 if string is valid. Invalid character is put to ch. 
int getInvalidUtf8SymbolPosition(const unsigned char *input, unsigned char &ch) { 
    int     nb, na; 
    const unsigned char *c = input; 

    for (c = input; *c; c += (nb + 1)) { 
    if (!(*c & 0x80)) 
     nb = 0; 
    else if ((*c & 0xc0) == 0x80) 
    { 
     ch = *c; 
     return (int)c - (int)input; 
    } 
    else if ((*c & 0xe0) == 0xc0) 
     nb = 1; 
    else if ((*c & 0xf0) == 0xe0) 
     nb = 2; 
    else if ((*c & 0xf8) == 0xf0) 
     nb = 3; 
    else if ((*c & 0xfc) == 0xf8) 
     nb = 4; 
    else if ((*c & 0xfe) == 0xfc) 
     nb = 5; 
    na = nb; 
    while (na-- > 0) 
     if ((*(c + nb) & 0xc0) != 0x80) 
     { 
      ch = *(c + nb); 
      return (int)(c + nb) - (int)input; 
     } 
    } 

    return -1; 
} 
+3

이 코드를 다시 사용하지 말고, 최단 형식 표현이 아닌 형식이 잘못된 UTF-8, 대리 코드 및 유니 코드 코드 공간 (U + 10FFFF)보다 높은 인코딩 된 코드 포인트를 허용합니다. – chansen

+0

chansen은 유효한 최단 형식 표현이며 유효한 UTF-8에서 금지 된 대리 문자입니까? 예를 들어, MSXML4.0이 UTF-8 인코딩 된 XML을 오류없이 이러한 기호로로드하는 것과 같은 방식으로 유효한 UTF-8 기호가 포함되어 있다고 생각했습니다. – izogfif

+0

izogfif, [The Unicode Standard Version 6.1] (http://www.unicode.org/versions/Unicode6.1.0/) - [3.9 유니 코드 인코딩 양식] (http://www.unicode.org/versions/Unicode6. 1.0/ch03.pdf) - UTF-8 D92 : "유니 코드 표준 3.1 이전 버전에서 UTF-8의 문제가되는"최단 형식이 아닌 "바이트 시퀀스는 BMP 문자가 여러 가지 방식으로 표현 될 수있는 바이트 시퀀스였습니다. 시퀀스는 표 3-7에서 허용되지 않기 때문에 부적절하다. " 대리 코드 포인트는 유니 코드 스칼라 값이 아니기 때문에 코드 포인트 D800..DFFF에 매핑되는 UTF-8 바이트 시퀀스는 부적절합니다. " – chansen

4

당신은 moreutils 컬렉션 isutf8를 사용할 수 있습니다. 쉘 스크립트에서

$ apt-get install moreutils 
$ isutf8 your_file 

--quiet 스위치를 사용하여 유효한 UTF-8있는 파일에 대한 제로 종료 상태를 확인합니다.

+0

입니다. https://rentes.github.io/unix/utilities/2015/07/27/moreutils-package/ – Oshanz