2017-12-13 10 views
3

정규화 후에도 다른 두 개의 유니 코드 문자열이 있습니다. 그러나 UTF-8로 인코딩 될 때는 동일합니다. 나는 그들이 어떻게 다른지 이해할 싶다.다른 유니 코드 문자열이 동일하게 인코딩됩니다.

그들은 식별자가 잘못 되었기 때문에 둘 다 엔티티의 식별자이며 조회가 실패합니다. 그러나 바이트 문자열은 같기 때문에 다른 유니 코드 문자열에 어떻게 도달했는지 이해하고 싶습니다. 다른 서브 시스템으로 처리되었습니다.) 그리고 실제로 어떻게 동일한 지 알 수있었습니다.

"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3"

과 :

"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\ud86b\ude18\ud854\udf14\u30c3"

문제는 정상화로 표시되지 않습니다. 나는이 질문의 요소들이 해답이 아니라는 것을 알고 있지만, 모든 단서를 고맙게 생각합니다!

>>> a = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\ud86b\ude18\ud854\udf14\u30c3" 
>>> b = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3" 
>>> a == b 
False 
>>> import unicodedata 
>>> unicodedata.normalize('NFKD', a) == unicodedata.normalize('NFKD', b) 
False 
>>> a.encode('UTF-8') == b.encode('UTF-8') 
True 
+6

문자 U + D86B 친구 즉, 대리 문자입니다. (실제) 코드 포인트를 U + FFFF 이상으로 인코딩하는 데 UTF16에서 사용되는 가짜 코드 포인트. 문자열'a'는 적절히 디코딩되지 않았습니다. @ snakecharmerb가 지적했듯이 최근 Python 버전에서는이 문자열이 손상된 것으로 간주합니다. 그러나 Python 2.7에서는 이것을 허용하는 것으로 보입니다. – lenz

답변

0

결과를 얻는 방법을 잘 모르겠습니다. 파이썬 2.7, 귀하의 ab 유니 코드 문자열은 동일합니다 :

>>> a = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\ud86b\ude18\ud854\udf14\u30c3" 
    >>> b = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3" 
    >>> a == b 
    True 
    >>> a 
    u'\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3' 
    >>> b 
    u'\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3' 

파이썬 2.7은 유니 코드 문자열을 저장하기 위해 내부적으로 UTF-16LE를 사용합니다. U + FFFF 위의 코드 점은 서로 게이트 (두 개의 16 비트 코드 단위)를 사용하여 저장됩니다. 다르게 입력하더라도 동일한 내용을 어떻게 표시하는지 유의하십시오. 두 문자열은 내부적으로 동일한 방식으로 구문 분석되고 저장됩니다. 또 다른 예 :

파이썬에서
>>> s = u'\U00025314' 
>>> len(s) 
2 
>>> hex(ord(s[0])) 
'0xd854' 
>>> hex(ord(s[1])) 
'0xdf14' 
>>> s = u'\ud854\udf14' 
>>> s 
u'\U00025314' 

이 3.3 이상 유니 코드를 내부적으로 저장되는 방식의 leaky abstraction 노출 구현 세부 사항이 수정되었습니다 :

>>> # python 3.3+ 
>>> s = '\U00025314' 
>>> len(s) 
1 
>>> hex(ord(s[0])) 
>>> hex(ord(s[0])) 
'0x25314' 
>>> s.encode('utf8') 
b'\xf0\xa5\x8c\x94' 

>>> s = '\ud854\udf14' 
>>> s 
'\ud854\udf14' 
>>> s.encode('utf8') 
Traceback (most recent call last): 
    File "<interactive input>", line 1, in <module> 
UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-1: surrogates not allowed