[10] [DFN[[RUBYB[サロゲートペア]@en[surrogate pair]]]]は、
[[UTF-16]] で2つの[[16ビット符号単位]]を組み合わせて1つの[[Unicode符号位置]]を表すものです。

[11] [[サロゲートペア]]で使う[[16ビット符号単位]]に相当する[[符号位置]]は、
([[符号化方式]]に関わらず) 使わないことになっています。

* 仕様書

[REFS[
- [53] [CITE[[[The Unicode Standard]], Version 13.0 - ch02.pdf]], [TIME[2020-03-09T17:53:32.000Z]], [TIME[2020-12-20T08:35:03.323Z]] <https://www.unicode.org/versions/latest/ch02.pdf#G14527>
- [46] 
[CITE[[[The Unicode Standard]], Version 13.0 - ch03.pdf]], [TIME[2020-03-09T17:53:34.000Z]], [TIME[2020-12-20T07:20:27.336Z]] 
<https://www.unicode.org/versions/latest/ch03.pdf#G22582>
- [44] [CITE[[[The Unicode Standard]], Version 13.0 - ch03.pdf]], [TIME[2020-03-09T17:53:34.000Z]], [TIME[2020-12-20T02:08:18.239Z]] <https://www.unicode.org/versions/latest/ch03.pdf#G2212>
-[49] 
[CITE[[[The Unicode Standard]], Version 13.0 - ch03.pdf]], [TIME[2020-03-09T17:53:34.000Z]], [TIME[2020-12-20T08:04:56.005Z]] <https://www.unicode.org/versions/latest/ch03.pdf#G2630>
- [26] 
[CITE[[[The Unicode Standard]], Version 13.0 - ch23.pdf]], [TIME[2020-03-09T17:53:52.000Z]], [TIME[2020-12-15T09:20:09.803Z]] <https://www.unicode.org/versions/latest/ch23.pdf#G24089>
]REFS]

* 符号点

[45] 
[DFN[[RUBYB[サロゲート][Surrogate]]]]は、
[[符号点型]]の1つです。
[SRC[>>44 D10a]]
[[General Category]]
[CODE[Cs]]
と同義です。
[SRC[>>53]]
[[サロゲート符号点]]は、
[[抽象文字]]に[[未割当済]]です。
[SRC[>>46 C1]]
([[未割当符号点]]ではなく[[割当済符号点]]ですが、[[抽象文字]]は[[未割当済]]です。)

[27] 
[DFN[[RUBYB[サロゲート領域][surrogates area]]]]の[[符号点]]
[DFN[[CODE[U+D800]]]] - [DFN[[CODE[U+DFFF]]]]
は、
[[UTF-16]]
で
[CODE[U+10000]] - [CODE[U+10FFFF]]
を記述するために2つ1組で使う[[16ビット符号単位]]、
[DFN[[RUBYB[サロゲート][surrogate]]]]です。
[SRC[>>26]]
[[サロゲート符号点]]は、
[[サロゲート符号単位]]として使われるためだけに割当られたものであり、
[[サロゲート符号単位]]は[[サロゲートペア]]にのみ使います
[SRC[>>49]]。

-
[28] 
[DFN[[RUBYB[[RUBY[高][こう]]サロゲート[RUBY[符号点][ふごうてん]]][high-surrogate code point]]]]
[CODE[U+D800]] - [DFN[[CODE[U+DBFF]]]] 
の1024個の[[Unicode符号点]]
[SRC[>>49 D71, >>26]]
([DFN[[RUBYB[[RUBY[高][こう]]サロゲート[RUBY[符号単位][ふごうたんい]]][high-surrogate code unit]]]]は
[[16ビット符号単位]]
[ [N[0xD800]], [N[0xDBFF]] ]
[SRC[>>49 D72]])
は、
[[サロゲートペア]]の先導[[符号単位]]に使います。
[SRC[>>49 D72, >>26]]
-- [31] 
[DFN[private-use high-surrogate code points]]
[DFN[[CODE[U+DB80]]]] - [CODE[U+DFFF]]
[SRC[>>26]]
は、
[[PUP]] 
の[[サロゲートペア]]の1つ目に使います。
-
[29] 
[DFN[[RUBY[[RUBY[低][てい]]サロゲート[RUBY[符号点][ふごうてん]]][low-surrogate code point]]]]
[DFN[[CODE[U+DC00]]]] - [CODE[U+DFFF]]
の1024個の[[符号位置]]
[SRC[>>49 D73, >>26]]
([DFN[[RUBYB[[RUBY[低][てい]]サロゲート[RUBY[符号単位][ふごうたんい]]][low-surrogate code unit]]]]は
[[16ビット符号単位]]
[ [N[0xDC00]], [N[0xDFFF]] ]
[SRC[>>49 D74]])
は、
[[サロゲートペア]]の後続[[符号単位]]に使います。
[SRC[>>49 D74, >>26]]


[35] 
[[Unicode]]
の[[ブロック]]名としての
[[High Surrogates]]
は、
[[High Private Use Surrogates]]
と重ならない
[DFN[[CODE[U+DB7F]]]]
までに限定されています。


[REFS[
- [55] [[符号点型]] [CODE[Surrogate]]
の[[符号点]]の一覧
<https://chars.suikawiki.org/set/%24unicode%3Anoncharacter>
- [43] [DFN[Surrogate]]
の符号点の一覧
<https://chars.suikawiki.org/set/%24unicode%3ASurrogate>
- [33] [DFN[[[High Surrogates]]]]
符号点の一覧
<https://chars.suikawiki.org/set/%24unicode%3ABlock%3AHigh_Surrogates>
- [32] [DFN[[[High Private Use Surrogates]]]]
符号点の一覧
<https://chars.suikawiki.org/set/%24unicode%3ABlock%3AHigh_Private_Use_Surrogates>
- [34] [DFN[[[Low Surrogates]]]]
符号点の一覧
<https://chars.suikawiki.org/set/%24unicode%3ABlock%3ALow_Surrogates>
]REFS]

* サロゲートペア

[50] 
[[サロゲート]]の組のことを[DFN[[RUBYB[サロゲートペア][surrogate pair]]]]といいます。
[SRC[>>26]]
[[サロゲートペア]]は、
2つの[[16ビット符号単位]]で構成される、
単一の[[抽象文字]]の表現です。
[[サロゲートペア]]では、
1つ目の[[符号単位]] ([DFN[leading surrogate]]) は[[高サロゲート符号単位]]、
2つ目の[[符号単位]] ([DFN[trailing surrogate]]) は[[低サロゲート符号単位]]とします。
[SRC[>>49 D75]]

[51] 
[[サロゲートペア]]は、
[[UTF-16]]
でのみ用います。
[SRC[>>49 D75]]



[FIG(railroad)[ [30] [[サロゲートペア]]
= =
== [[high surrogate]]
== [[low surrogate]]
]FIG]


* 孤立サロゲート

[36] 
[[サロゲート]]は、
[[UTF-16]]
の特殊な用途のためのみに使うこととされています。
[[UTF-16]]
以外でも、
[[サロゲート]]の[[符号位置]]を使うことはできません。

[52] 
[RUBYB[孤立][isolated]][[サロゲート符号点]]は、
それ自体の解釈を持ちません。
[SRC[>>49 D75]]


[48] 
[[Unicode符号点]]には[[サロゲート符号点]]も含まれます。
[[Unicodeスカラー値]]には[[サロゲート符号点]]が含まれません。

[38] 
ただし
[[UTF-16]]
による[[文字列]]の実装の中には、
[[サロゲートペア]]になっていない[[サロゲート]]の出現を認めるものも少なくありません。
それ以外の [[UTF-8]] などによる[[文字列]]の実装の中には、
[[サロゲート]]の出現を認めるものが多いです。
こうしたものは[[サロゲートペア]]として1つの[[文字]]を表すのではなく、
不正な[[符号位置]]とみなされます。

[39] 
そうした不正な[[サロゲート]]を含んだ[[文字列]]を扱えない実装もあり、
[[相互運用性]]の問題や[[セキュリティー]]の問題につながることもありますから、
要注意です。

[40] 
不正な[[サロゲート]]を含んだ[[文字列]]を
[[UTF-16]]
として出力すると、
不正な[[サロゲート]]が正当な[[サロゲートペア]]と解釈されてしまうことがあります。
[[相互運用性]]の問題や[[セキュリティー]]の問題につながることもありますから、
要注意です。


[42] 
[[文字列]]に対する操作を扱う[[プロトコル]]や[[演算]]の[[仕様書]]は、
入力に不正な[[サロゲート]]が含まれないことを暗黙に仮定していることがあります。
不正な[[サロゲート]]を認める実装は、
適宜例外処理を入れる必要があります。

-*-*-

[59] [[Python]] は[[surrogateescape]]と称して[[バイト]]を表すために流用しています。

[60] [[skf内部コード]]は内部処理用に[[サロゲート符号位置]]を使っています。

* 符号化方式

[12] 次の[[符号化方式]]で[[サロゲートペア]]が使われました。
[FIG(short list)[
- [[UTF-16]]
- [[CESU-8]]
- [[UTF-32S]]
]FIG]

[37] 
[CITE[Encoding Standard]]
に従う[[復号]]の実装は、
[[UTF-8]]
の入力の[[バイト列]]に[[サロゲート]]があると、
[CODE[U+FFFD]]
を生成します。
[[UTF-32]] その他、[[サロゲートペア]]を使わない他の
[[Unicode]]
系[[文字コード]]の実装も、同じように扱うべきでしょう。

[41] 
[CITE[Encoding Standard]]
の従う[[復号]]の実装は、
[[UTF-16]]
の入力の[[バイト列]]に[[サロゲートペア]]になっていない[[サロゲート]]があると、
[CODE[U+FFFD]]
を生成します。

* 処理

[47] 
[[処理]]は、
[[高サロゲート符号点]]と[[低サロゲート符号点]]を[[抽象文字]]と解釈してはなりません。
[SRC[>>46 C1]]

* プロトコル要素とサロゲートペア

[57] [[JSON]]

[58] [[文字参照]]

* 関連

[61] [[Shift-Mojikyo]] は独自の[[サロゲートペア]]機能を持っています。

* 歴史

[1]
[CITE@en[I'm not a Klingon : UTF-16, UTF-8 & UTF-32 update to conform with Unicode 5.0's security concerns.]] ([TIME[2007-07-27 23:26:23 +09:00]] 版) <http://blogs.msdn.com/shawnste/archive/2007/07/23/utf-16-utf-8-utf-32-update-to-conform-with-unicode-5-0-s-security-concerns.aspx>

[2] [CITE@en[Web Applications 1.0 r7084     Make WebSocket silently convert isolated surrogated to U+FFFD rather than throwing an exception. This will result in data corruption when a user types in astral-plane characters that get truncated by naiive script half-way through, rather than crashing the application.]]
( ([TIME[2012-05-03 05:06:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7083&to=7084>

[3] [CITE@en[Notifications API: minor change]]
( ([[Anne van Kesteren]] 著, [TIME[2012-11-30 00:03:40 +09:00]] 版))
<http://lists.w3.org/Archives/Public/public-web-notification/2012Nov/0010.html>

[4] [CITE[IRC logs: freenode / #whatwg / 20130915]]
( ([TIME[2013-09-16 22:06:01 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20130915#l-241>

[5] [CITE[IRC logs: freenode / #whatwg / 20101111]]
( ([TIME[2010-11-19 23:02:05 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20101111#l-579>

[6] [CITE@en[Web Applications 1.0 r6184     Try to clean up the stuff about Unicode characters.]]
( ([TIME[2011-06-04 04:40:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=6183&to=6184>


[7] [CITE[IRC logs: freenode / #whatwg / 20140329]]
( ([TIME[2014-03-31 13:06:30 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140329>

[8] [CITE[IRC logs: freenode / #whatwg / 20140516]]
( ([TIME[2014-05-21 16:29:26 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20140516>

[9] [CITE@en[''''''[''''''CSSWG'''''']'''''' Minutes Seoul F2F 2014-05-19 Part V: Counter Styles, CSS  Formatting for Books, Font Load Events, Future F2F Meetings, CSS Syntax -  Unpaired Surrogates, MQ Listener]]
( ([[Dael Jackson]] 著, [TIME[2014-06-09 08:42:57 +09:00]] 版))
<http://lists.w3.org/Archives/Public/www-style/2014Jun/0060.html>

[13] [CITE@en[Define JavaScript string and scalar value string]]
([[annevk]]著, [TIME[2017-03-27 16:01:49 +09:00]])
<https://github.com/whatwg/infra/commit/f1be763cfba23d2fc780b35403074c599e69616e>

[14] [CITE@en['''['''c''']''' (2) Disallow surrogates in the input stream; make the syntax sect…]]
([[Hixie]]著, [TIME[2013-09-14 06:27:11 +09:00]])
<https://github.com/whatwg/html/commit/6dfaa1a826fae1dd50695710498434d201e543f6>

[15] [CITE@en['''['''''']''' (0) Catch unpaired surrogates before trying to convert them to UTF-8.]]
([[Hixie]]著, [TIME[2009-06-13 07:33:53 +09:00]])
<https://github.com/whatwg/html/commit/53f640d41e2aadfde9cada86d3046d5912ecc818>

[16] [CITE@en['''['''ct''']''' (2) Make surrogates in UTF-8 and character references turn into …]]
([[Hixie]]著, [TIME[2009-09-16 18:22:01 +09:00]])
<https://github.com/whatwg/html/commit/6db21943d024e774d2aa52573981c130767034e9>

[17] [CITE@en['''['''t''']''' (0) Remove the requirement that the parser deal with raw surrogat…]]
([[Hixie]]著, [TIME[2011-02-09 09:29:12 +09:00]])
<https://github.com/whatwg/html/commit/3accfd8a1893d91cb3cdbae62b6d8980e456dda6>

[18] [CITE@en['''['''giow''']''' (0) Fix the UTF-8 decoder error handling to handle a few error…]]
([[Hixie]]著, [TIME[2011-03-04 11:56:49 +09:00]])
<https://github.com/whatwg/html/commit/74e3b6cb761ee8a79b3a1a44d029c128fd0a201f>

[19] [CITE@en['''['''giow''']''' (0) Unpaired surrogates should throw an exception in close, li…]]
([[Hixie]]著, [TIME[2011-06-22 08:01:17 +09:00]])
<https://github.com/whatwg/html/commit/226e15ebd3d557a67bedcfc043e165d24e4182c1>

[20] [CITE@en['''['''giow''']''' (1) Make WebSocket silently convert isolated surrogated to U+F…]]
([[Hixie]]著, [TIME[2012-05-03 05:06:23 +09:00]])
<https://github.com/whatwg/html/commit/a817b04f4c262645ef996a5176b4a3f0a3a11928>

[21] [CITE@en['''['''c''']''' (2) Disallow surrogates in the input stream; make the syntax sect…]]
([[Hixie]]著, [TIME[2013-09-14 06:27:11 +09:00]])
<https://github.com/whatwg/html/commit/6dfaa1a826fae1dd50695710498434d201e543f6>

[22] [CITE@en['''['''cssom''']''' Add IDL `CSSOMString`, typedef of either USVString or DOMString]]
([[SimonSapin]]著, [TIME[2017-04-21 12:28:09 +09:00]])
<https://github.com/w3c/csswg-drafts/commit/830ae19ffd9a6fa6eb60aa21549d334cb18fb706>

[23] [[サロゲートペア]]の ([[UTF-16]] の) 支持者は、
不支持者に対して、「[[サロゲートペア]]の処理は[[結合文字]]の処理より簡単だ、
どのみち[[結合文字]]の処理は必要だから大した問題ではない」
と返すのが (十数年にわたってw) 定番となっています。

[24] [[文字符号化]]のレイヤーと[[文字]]の処理のレイヤーが混ざっているのは20世紀のソフトウェア開発技法だと思うんですがねぇ。
([[シフトJIS]]は[[半角]]と[[全角]]が[[バイト数]]と一致するから表示処理が楽だ、
みたいなのと同じでしょう。)

[25] [CITE@en['''['''css-syntax''']''' Remove 'code point' and 'surrogate code point' in favor …]]
([[tabatkins]]著, [TIME[2017-06-10 03:59:51 +09:00]])
<https://github.com/w3c/csswg-drafts/commit/320a990184a331057a56a17cdf627fee81bdc5d3>

[54] [CITE@en-us[Unicode Character Encoding Stability Policy]]
( ([TIME[2013-06-27 23:43:16 +09:00]] 版))
<http://www.unicode.org/policies/stability_policy.html#Property_Value>



[56] [CITE@en[ston/ston-spec.md at master · svenvc/ston]]
([TIME[2021-09-26T01:40:23.000Z]])
<https://github.com/svenvc/ston/blob/master/ston-spec.md#strings>