유니코드 문자 검사기

텍스트를 코드 포인트로 분해해 이름, 범주, 블록, 인코딩을 표시. 보이지 않는 문자, 양방향 제어, 닮은꼴 문자도 감지합니다.

입력

이 도구가 하는 일

아무 텍스트나 붙여넣으면 그것이 실제로 이루어진 개별 문자로 분해되어 돌아옵니다. 각각이 유니코드 이름, U+ 번호, 어떤 종류의 문자인지, 어느 문자 체계와 블록에 속하는지, UTF-8과 UTF-16에서 차지하는 바이트, 그리고 여섯 가지 다른 형식의 이스케이프 나열을 얻습니다.

대부분의 사람은 무언가가 맞지 않아 여기 옵니다. 문자열이 보기보다 길거나, 똑같이 표시되는 두 값이 같게 비교되기를 거부하거나, 맨 글자처럼 보이는 것 때문에 사용자 이름이 거부되었거나, 소스 코드 한 줄이 동작과 다르게 읽힙니다. 넷 다 같은 모양입니다: 화면이 보이지 않는 무언가를 하는 문자입니다.

문자, 코드 포인트, 자소

"문자"라는 말은 적어도 세 가지 다른 것을 뜻하고, 그것들을 뒤섞는 데서 대부분의 유니코드 혼란이 시작됩니다. 코드 포인트는 유니코드 표준의 값 하나로, U+0041이나 U+1F600으로 쓰입니다. 자소는 읽는 사람이 한 글자로 세는 것입니다. 둘은 흔히 같은 수가 아닙니다.

  • 맨 "a"는 자소 1, 코드 포인트 1, UTF-16 단위 1 — 모두 일치합니다.
  • U+00E9, 미리 합성된 e-악센트는 자소 1, 코드 포인트 1, UTF-16 단위 1입니다.
  • U+0065 U+0301, e에 결합 악센트를 이은 같은 글자는 자소 1이지만 코드 포인트 2, UTF-16 단위 2입니다.
  • U+1F600, 활짝 웃는 얼굴은 자소 1, 코드 포인트 1이지만 UTF-16 단위 2입니다 — BMP 위에 살아 JavaScript가 그것을 서로게이트 쌍으로 저장합니다.
  • 가족 이모지는 자소 1, 코드 포인트 5, UTF-16 단위 8입니다: 두 개의 보이지 않는 결합자로 이어진 세 사람.

가족 이모지가 사람을 걸리는 경우입니다. 한 가지로 보이는데 JavaScript는 그 길이를 8로 보고하고, 5글자 데이터베이스 열은 그것을 담지 못합니다. 이 도구는 코드 포인트를 그것이 이루는 자소 아래에 묶어, 머릿속에서 맞춰야 하는 대신 두 읽기가 한꺼번에 보이게 합니다.

볼 수 없는 문자

놀랄 만큼 많은 유니코드 문자가 아무것도 그리지 않습니다. 주변 텍스트가 어떻게 동작할지 제어하려고 있고, 자국을 남기지 않으므로 아무도 눈치채지 못한 채 복사, 붙여넣기, 검토를 살아남습니다. 이것들이 그저 나열하지 않고 이 도구가 짚는 것입니다:

  • 폭 없는 공백, 결합자, 비결합자(U+200B, U+200D, U+200C) — 폭도 자국도 없고, 닿는 모든 문자열 비교를 깨뜨립니다.
  • 소프트 하이픈(U+00AD) — 단어가 어디서 끊길 수 있는지에 대한 제안으로, 끊길 때까지 보이지 않습니다.
  • 줄바꿈 없는 공백(U+00A0) — 공백과 똑같아 보이고 다른 문자라, 설정 파일에서 그토록 오래 살아남습니다.
  • 바이트 순서 표시(U+FEFF) — 흔히 파일 맨 앞에 남아, 거기서 첫 값의 보이지 않는 첫 문자가 됩니다.
  • 양방향 제어와 재정의(U+202A~U+202E, U+2066~U+2069) — 주변 텍스트를 재배열합니다.

양방향 제어는 따로 언급할 만합니다. 히브리어와 아랍어가 라틴 텍스트와 올바르게 섞이도록 더해졌고, 그 일을 잘 해냅니다. 하지만 주석이나 문자열 리터럴 안에 놓인 재정의는 소스 코드 한 줄을 컴파일러가 읽는 순서와 완전히 다른 순서로 표시하게 할 수 있습니다 — 즉 검토자가 전혀 다른 것을 하는 코드를 승인할 수 있습니다. 그런 종류의 수법은 Trojan Source라 알려져 있고, 그래서 이 도구는 모든 양방향 제어를 다른 보이지 않는 문자와 따로 짚습니다.

닮은꼴 문자와 혼합 문자 체계

유니코드에는 ASCII 글자와 시각적으로 동일하면서 그것이 아닌 문자가 많습니다. 키릴 а, 그리스 ο, 라틴 a는 다른 코드 포인트를 차지하고 대부분의 폰트에서 같게 그려집니다. 그것들로 만든 도메인이나 사용자 이름은 옳아 보이면서 다른 곳을 가리킵니다.

모든 비ASCII 닮은꼴을 짚는 것은 쓸모없을 것입니다: 모든 러시아어, 그리스어, 히브리어 단어를 빨갛게 칠하고, 보통 텍스트에 반응하는 경고는 사람이 넘기기를 배우는 경고입니다. 그래서 여기 규칙은 유니코드 보안 표준이 쓰는 것입니다 — 단어는 그 안의 글자가 둘 이상의 문자 체계에서 올 때 의심스럽습니다:

  • 모두 라틴 글자로 쓰인 "paypal.com": 할 말이 없습니다.
  • 라틴 "ypal" 앞에 키릴 er과 a를 붙인 같은 단어: 한 단어, 두 문자 체계, 짚힙니다.
  • 키릴로 된 러시아어 단어 전체: 한 문자 체계, 보통 텍스트, 짚히지 않습니다.
  • Han, 히라가나, 가타카나를 함께 쓰는 일본어 문장: 세 용자, 한 문자 체계, 짚히지 않습니다.

그 마지막 경우가 규칙에 주의가 필요한 이유입니다. 일본어는 세 용자를 한꺼번에 써서 쓰이고 한국어는 둘을 섞으므로, 순진한 "둘 이상의 용자는 의심스럽다" 검사는 모든 일본어 문장을 공격이라 부를 것입니다. 정말로 한 문자 체계인 조합은 하나로 다뤄져, 경고를 의미 있게 유지합니다.

정규화, 또는 왜 동일한 두 문자열이 다른가

어떤 문자는 여러 방식으로 쓸 수 있습니다. 글자 é는 단일 코드 포인트 U+00E9이거나 쌍 U+0065 U+0301 — 맨 e에 결합 예음 악센트를 이은 것 — 중 하나입니다. 둘 다 똑같이 표시됩니다. 어느 쪽도 틀리지 않았습니다. 그것들은 같지 않습니다.

정규화는 하나의 철자를 고르는 과정이고, 네 형식이 있습니다. NFC는 될 수 있는 곳에서 합성하며 웹이 기본으로 가정하는 것이고, NFD는 대신 분해합니다. 두 K 형식은 더 나아가 호환 문자도 접습니다 — 전각 A가 맨 A가 되고, 합자 fi가 fi가 됩니다 — 이는 검색과 대조에 유용하고 저장에는 손실이 있습니다.

여기 패널은 붙여넣은 것의 네 형식 모두를 보이고 그중 어느 것이 입력과 다른지 표시합니다. 어느 것도 다르지 않으면 텍스트는 이미 정규화되어 있고 쫓던 어긋남은 다른 데 있습니다. 몇 개가 다르면 그것을 찾은 것입니다.

이름, 범주, 용자, 블록

할당된 모든 문자는 네 조각의 정체를 지니고, 그것들은 다른 물음에 답합니다. 이름은 문자 그 자체입니다. 일반 범주는 그것이 어떤 종류인지 — 소문자, 결합 문자, 통화 기호, 서식 제어 — 를 말합니다. 용자는 그것이 속한 문자 체계입니다. 블록은 그것이 할당된 코드 포인트의 범위로, 언어적이 아니라 조직상의 사실입니다.

블록과 용자는 헷갈리기 쉽고 흔히 어긋납니다. 라틴 글자는 적어도 여섯 개 블록에 살고, 한 블록이 여러 용자의 문자를 담을 수 있습니다. "이것이 무슨 알파벳인가"를 알고 싶으면 용자가 답이고, "이것이 표준의 어디에 사는가"를 알고 싶으면 블록입니다.

이름, 용자, 블록은 어느 언어에서든 여기서 일부러 영어로 표시됩니다. 그것들은 표준이 정하는 식별자이지 산문이 아니라 — U+200D는 세계 어디서나 ZERO WIDTH JOINER라 이름 붙고, 그것을 번역하면 검색할 수 없게 됩니다.

인코딩과 이스케이프

코드 포인트는 수이고, 인코딩이 골라져야 비로소 바이트가 됩니다. UTF-8은 1에서 4바이트를 쓰고 ASCII를 그대로 두어, 그래서 이겼습니다. UTF-16은 하나나 두 개의 16비트 단위를 쓰고, JavaScript 문자열이 이루어진 것입니다 — 그래서 .length가 단일 이모지에 2를 보고합니다.

U+0041   41              # UTF-8: 1바이트, ASCII와 같음
U+00E9   C3 A9           # UTF-8: 2바이트
U+20AC   E2 82 AC        # UTF-8: 3바이트
U+1F600  F0 9F 98 80     # UTF-8: 4바이트

여기 각 행은 문자를 JavaScript, JSON, HTML, CSS, URL, Python에서의 이스케이프로도 주어 복사할 수 있게 합니다. 그것들이 모두 같지는 않고, 그 차이는 BMP 위에서 중요합니다: JavaScript와 Python은 코드 포인트 이스케이프를 지녀 쓰고, JSON은 그것이 없어 이모지를 두 개의 서로게이트 반쪽으로 철자해야 합니다.

숨은 문자, 그리고 AI 모델에서 나온 텍스트

여기 붙여넣는 텍스트의 상당수는 붙여넣는 사람이 직접 친 것이 아닙니다. 문서에서, 웹 페이지에서, 티켓에서, 또는 어시스턴트의 답변에서 복사해 온 것이고, 함께 오는 물음은 볼 수 없는 문자를 달고 오지 않았는가입니다. 이 도구가 답하는 것이 바로 그것이고, 답이 어디까지 미치는지 말해 둘 값이 있습니다. 텍스트는 코드 포인트로 분해되고, 표준이 이름을 준 것에는 그 이름이 붙으며, 한 번 더 볼 만한 것들은 목록 위의 한 줄에서 세어집니다. 그 줄이 나오지 않으면 아무것도 찾지 못한 것입니다.

숨은 문자가 증명하는 바는 이 주제로 쓰인 글 대부분이 내비치는 것보다 좁습니다. 코드 포인트 안에는 그것이 어디서 왔는지가 기록되어 있지 않습니다. 콘텐츠 관리 시스템에서 복사해 들어온 것과 생성된 답변과 함께 들어온 것은 같은 값입니다. 대규모 언어 모델의 출력에서 보이지 않는 문자가 보고된 일은 실제로 있었고, 가장 많은 주목을 받은 사례 — 보통 공백이 들어갈 자리에 나타난 좁은 줄바꿈 없는 공백 — 에서 모델 제작사는 일부러 넣은 것이 아니라 훈련의 부산물이라고 답했으며, 보고는 며칠 만에 끊겼습니다. 그러니 여기서의 발견은 무엇을 지울지 알려 줍니다. 무엇이 그 문장을 썼는지는 알려 주지 않습니다.

  • 보통 공백이 아닌 공백. 줄바꿈 없는 공백(U+00A0)과 좁은 줄바꿈 없는 공백(U+202F)이 가장 자주 거론됩니다. 둘 다 대략 공백만 한 폭이고, 둘 다 다른 문자이며, 이 도구는 둘 다 짚습니다.
  • 폭이 아예 없는 문자. 폭 없는 공백(U+200B), 워드 조이너(U+2060), 바이트 순서 표시(U+FEFF)는 아무것도 그리지 않고, 검토를 살아남으며, 닿는 첫 비교를 깨뜨립니다. 보이지 않는 문자로 짚힙니다.
  • Tags 블록(U+E0000부터 U+E007F까지). 인쇄 가능한 ASCII 문자마다 보이지 않는 코드 포인트를 하나씩 갖고 있어 — U+E0041의 이름은 TAG LATIN CAPITAL LETTER A입니다 — 아무것도 보여 주지 않는 텍스트 안에 문장 하나를 통째로 철자할 수 있습니다. 여기서는 그 하나하나에 이름이 붙고 보이지 않는 문자로 짚힙니다.
  • 탓을 듣지만 숨어 있지 않은 문장 부호. 엠 대시(U+2014)와 오른쪽 작은따옴표(U+2019)는 보이는 자국을 그리므로 여기서는 아무것도 짚지 않습니다. 무엇이 만들어 냈든 평범한 조판입니다.

확인할 이유 두 가지는 갈라 두는 편이 낫습니다. 일상적인 쪽은 보이지 않는 문자가 조용히 일을 망친다는 것입니다 — 맞아야 할 비교, 조회 키, 이유도 말하지 않고 입력을 거부하는 항목. 다른 쪽은 텍스트를 사람만큼이나 프로그램도 읽는다는 것입니다. Tags 블록의 문자는 언어 표시를 위해 마련되었고 대부분의 편집기와 diff에서는 아무것도 그리지 않지만, 텍스트를 보는 대신 읽는 것은 그래도 읽습니다. 긴 답변을 통째로 붙여넣을 때는, 행 목록은 잘리고 개수는 잘리지 않는다는 점에 유의하세요 — 개수는 붙여넣은 전부에 대해 세어집니다.

자주 묻는 질문

제 문자열이 보이는 글자 수보다 긴 이유는 무엇인가요?
보이지 않는 문자를 담았거나 여러 코드 포인트로 이루어진 자소를 담았거나 둘 중 하나입니다. 둘 다 여기 보입니다: 보이지 않는 문자는 짚히고, 여러 코드 포인트의 자소는 묶여 한 문자와 그것이 이루어진 여러 값이 보입니다.
두 문자열이 동일해 보이는데 같지 않습니다. 왜인가요?
대개 정규화입니다. 악센트 붙은 글자는 코드 포인트 하나이거나 글자에 결합 문자를 더한 것일 수 있고, 둘 다 같게 표시됩니다. 각 문자열을 여기 붙여넣어 코드 포인트 목록을 비교하거나, 어느 정규화 형식이 입력과 다른지 보세요.
폭 없는 공백이란 무엇이고 어떻게 제 텍스트에 들어왔나요?
폭도 자국도 없는 문자로, 줄바꿈 기회를 제안하는 데 쓰입니다. 대개 웹 페이지, 문서 편집기, 채팅 클라이언트에서 텍스트를 복사해 들어오고, 아무것도 표시되지 않으므로 무언가가 문자열을 비교해 실패할 때까지 모든 검토를 살아남습니다.
코드 포인트와 문자의 차이는 무엇인가요?
코드 포인트는 유니코드 값 하나입니다. 일상적 의미의 문자는 자소 — 읽는 사람이 하나로 세는 것 — 이고, 자소는 여러 코드 포인트일 수 있습니다. 가족 이모지는 다섯 코드 포인트와 한 자소입니다.
도구가 어떤 문자에 이름이 없다고 하는 이유는 무엇인가요?
네 가지 다른 이유가 있고, 어느 것인지 말합니다. 서로게이트와 사용자 영역 코드 포인트는 표준에 이름이 없고, 할당되지 않은 것은 이름 붙일 것이 없고, 좀처럼 살피지 않는 역사적 블록의 문자는 이 빌드가 지니지 않은 이름을 지닙니다 — 이름 표는 전부를 싣기보다 사람이 실제로 붙여넣는 블록을 지닙니다.
혼합 문자 체계 경고가 공격의 증거인가요?
아니요. 한 단어가 둘 이상의 문자 체계에서 글자를 끌어옴을 뜻하고, 그것은 위장된 이름이 지니는 모양이자 보통 텍스트가 이따금 하는 것이기도 합니다. 볼 이유이지 판정이 아닙니다.
제가 붙여넣은 것이 서버로 전송되나요?
아니요. 문자 데이터베이스는 페이지와 함께 내려받고 모든 것이 브라우저 안에서 돕니다. 입력한 내용이 업로드·기록되지 않고, 네트워크 연결 없이 동작합니다.
AI 모델의 텍스트에 보이지 않는 문자가 들어 있나요?
때때로 있고, 무언가를 식별할 수 있는 방식으로는 결코 아닙니다. 가장 많은 주목을 받은 것은 긴 답변에서 보통 공백이 들어갈 자리에 나타난 좁은 줄바꿈 없는 공백(U+202F)이었습니다. 모델 제작사는 일부러 넣은 것이 아니라 훈련의 부산물이라고 답했고, 며칠 만에 더는 보이지 않게 되었습니다. 텍스트를 여기 붙여넣으면 그 안에 무엇이 있는지 보입니다. 보이지 않는 것은 그것이 어디서 왔는가이고, 코드 포인트는 그것을 기록하지 않기 때문입니다.
텍스트에서 숨은 문자를 어떻게 찾고 지우나요?
찾으려면 여기에 붙여넣으세요. 모든 코드 포인트가 한 행씩 나오고, 이름이 있는 것에는 그 이름이 붙고, 한 번 더 볼 만한 것들은 목록 위에서 세어집니다. 지우는 일은 편집기의 몫이고 — 여기서는 무엇도 당신의 텍스트를 다시 쓰지 않습니다 — 다만 어떤 코드 포인트를 쫓는지 알고 나면, 각 행이 그것을 여섯 가지 형식의 이스케이프로 줍니다. 이스케이프를 알아듣는 검색창이 원하는 것이 그것입니다.
엠 대시나 둥근 따옴표가 숨은 문자인가요?
아니요. 엠 대시(U+2014)와 오른쪽 작은따옴표(U+2019)는 둘 다 화면에 자국을 그리므로 여기서는 아무것도 짚지 않습니다. 생성된 글의 표시로 자주 제시되지만, 그것은 문체의 문제이고 문자 검사기가 답할 수 있는 것이 아닙니다. 그래도 다른 이유로 알아 둘 값이 있습니다. 둘 다 ASCII가 아니므로 ASCII를 기대하는 것을 괴롭힐 수 있고, 이것들로 쓴 문자열은 하이픈과 곧은 아포스트로피로 친 같은 문자열과 같지 않습니다.

관련 도구