Surrogate pair

Tori·2024년 11월 18일

JavaScript

목록 보기
4/7
post-thumbnail

javascript info 서로게이트 쌍 참고

문자열을 입력받아 어떤 처리를 하는 알고리즘 문제를 풀다가 생각지 못한 이슈가 있었다.
예를 들어서 'Hello'라는 문자열이 입력됐을 때 단순히 split('')으로 각 문자를 접근해서 문제를 해결했었는데 이모티콘에서는 예상했던 것과 다르게 동작하는 문제점이 있었다.

이모티콘에서 split, spread를 사용했을 때 다른 동작이 일어난다.



split과 spread의 동작 방식

이모티콘 문자열 "🐝💕🐙"의 유니코드 표현

🐝 (벌): U+1F41D

  • High Surrogate: 0xD83D (U+D83D)
  • Low Surrogate: 0xDC1D (U+DC1D)

💕 (두 개의 하트): U+1F496

  • High Surrogate: 0xD83D (U+D83D)
  • Low Surrogate: 0xDC96 (U+DC96)

🐙 (문어): U+1F419

  • High Surrogate: 0xD83D (U+D83D)
  • Low Surrogate: 0xDC19 (U+DC19)



split('')

동작 원리

  • split('') 메서드는 문자열을 빈 문자열을 기준으로 나누어 각 문자(또는 코드 유닛)를 배열의 요소로 반환한다.
  • 이모티콘과 같은 Surrogate Pair를 가진 문자는 각 코드의 유닛으로 나눠진다.

예)

const emojiString = '🐝💕🐙';
const result = emojiString.split('');
console.log(result);

결과)

// ['\uD83D', '\uDC1D', '\uD83D', '\uDC95', '\uD83D', '\uDC19']



spread [...]

동작 원리

  • 스프레드 연산자는 iterable 객체(문자열 포함)의 각 요소를 개별적으로 나누어 새로운 배열을 생성한다.
  • 이 경우, 문자열의 각 코드 유닛을 개별적으로 나누어 배열로 만든다.
  • 이모티콘 문자열 '🐝💕🐙'는 각 이모티콘이 전체로 처리되어 배열의 각 요소로 반환된다.

예)

const emojiString = '🐝💕🐙';
const result = [...emojiString];
console.log(result);

결과)

// ['🐝', '💕', '🐙']



결론

  • split('')는 이모티콘을 구성하는 각 코드 유닛으로 나누어 반환하는 반면,
    스프레드 연산자는 이모티콘을 전체로 처리하여 배열의 각 요소로 반환한다.

  • 이 두 방법은 이모티콘을 처리하는 방식이 다르므로, 결과도 다르게 나타난다.





surrogate pair란

Surrogate Pair는 UTF-16 인코딩에서 사용되는 개념으로, 16비트(2바이트)로 표현할 수 없는 유니코드 문자를 표현하기 위해 두 개의 16비트 코드 유닛을 사용하는 방법이다.
이는 주로 유니코드의 코드 포인트가 0x10000(65536) 이상의 문자에 해당할 때 사용된다.



유니코드와 UTF-16

유니코드:

  • 유니코드는 전 세계의 모든 문자를 표현하기 위한 표준이다.
  • 각 문자는 고유한 코드 포인트를 가지고 있다. (예를 들어, 'A'는 U+0041, '가'는 U+AC00입니다.)

UTF-16:

UTF-16에 대한 설명을 아래에서 더 자세히 다루겠다.

  • UTF-16은 유니코드를 인코딩하는 방법 중 하나로, 기본적으로 16비트(2바이트) 단위로 문자를 표현한다.
  • 그러나 16비트로 표현할 수 없는 문자는 Surrogate Pair를 사용하여 두 개의 16비트 코드 유닛으로 표현한다.



Surrogate Pair의 구조

Surrogate Pair는 두 개의 16비트 코드 유닛으로 구성된다:

1. High Surrogate: 0xD800에서 0xDBFF 사이의 값으로, 상위 16비트이다.
2. Low Surrogate: 0xDC00에서 0xDFFF 사이의 값으로, 하위 16비트입이다.

이 두 개의 코드 유닛을 결합하여 하나의 유니코드 코드 포인트를 표현한다.

예를 들어, 코드 포인트 U+10000은 다음과 같이 표현됩니다:
High Surrogate: 0xD800
Low Surrogate: 0xDC00



Surrogate Pair의 예

U+10000 (65536) → Surrogate Pair: 0xD800 0xDC00
U+1F600 (😀) → Surrogate Pair: 0xD83D 0xDE00



Surrogate Pair의 사용

Surrogate Pair는 주로 다음과 같은 경우에 사용된다:

  • 이모지: 많은 이모지와 특수 문자는 Surrogate Pair를 사용하여 표현다.
  • 희귀 문자: 다양한 언어의 희귀 문자나 고대 문자도 Surrogate Pair로 표현될 수 있습니다.



모든 언어에서의 적용

Surrogate Pair는 UTF-16 인코딩을 사용하는 시스템에서만 적용된다.
따라서 모든 프로그래밍 언어나 시스템에서 공통적으로 적용되는 개념은 아니다.

예를 들어:

UTF-8:

UTF-8은 가변 길이 인코딩 방식으로, Surrogate Pair 개념이 필요하지 않다.
UTF-8에서는 1바이트에서 4바이트까지 사용하여 모든 유니코드 문자를 표현할 수 있습니다.

UTF-32:

UTF-32는 고정 길이 인코딩 방식으로, 모든 유니코드 문자를 4바이트로 표현하므로 Surrogate Pair가 필요하지 않다.



결론

  • Surrogate Pair는 UTF-16 인코딩에서만 사용되는 개념으로, 모든 언어에서 공통적으로 적용되는 것은 아니다.
  • 각 인코딩 방식에 따라 문자를 표현하는 방법이 다르므로, Surrogate Pair는 UTF-16을 사용하는 시스템에서만 관련이 있다.





자바스크립트 문자열 UTF-16 인코딩 처리

JavaScript는 내부적으로 문자열을 UTF-16 인코딩 방식으로 처리한다.
이는 JavaScript의 문자열이 16비트 코드 유닛으로 구성된다는 것을 의미합니다.

UTF-16 인코딩

16비트 코드 유닛:

JavaScript의 문자열은 기본적으로 16비트(2바이트) 단위로 구성된다.

이는 ASCII 문자와 같은 기본 문자들은 1개의 16비트 코드 유닛으로 표현되지만, 유니코드의 더 높은 코드 포인트(예: 이모티콘, 특정 언어의 문자 등)는 Surrogate Pair를 사용하여 두 개의 16비트 코드 유닛으로 표현됩니다.

Surrogate Pair:

UTF-16에서 0x10000 이상의 코드 포인트는 두 개의 16비트 코드 유닛으로 나누어 표현된다.

예를 들어, 이모티콘 '🐝' (U+1F41D)는 다음과 같이 표현:
High Surrogate: 0xD83D
Low Surrogate: 0xDC1D

문자열 처리:

JavaScript에서 문자열을 다룰 때, 문자열의 길이는 16비트 코드 유닛의 수로 계산된다.
따라서 Surrogate Pair를 사용하는 문자는 문자열의 길이를 계산할 때 두 개의 코드 유닛으로 간주된다.

예)

const emoji = '🐝';
console.log(emoji.length); // 2 (Surrogate Pair로 인해 두 개의 코드 유닛으로 계산됨)

const str = 'Hello, World!';
console.log(str.length); // 13 (각 문자가 1개의 16비트 코드 유닛으로 표현됨)

결론

JavaScript는 UTF-16 인코딩을 사용하여 문자열을 처리하며, 이는 문자열의 각 문자가 16비트 코드 유닛으로 표현된다는 것을 의미한다.
이로 인해 Surrogate Pair를 사용하는 문자는 문자열의 길이를 계산할 때 두 개의 코드 유닛으로 간주된다.

profile
🌿

0개의 댓글