サロゲートペア

2024年01月16日(火) 09時36分更新 icon 項目のみ表示/展開表示の切り替え

サロゲートペア

Unicodeでは2byte(65536種類)で全世界の字を取り込む予定でしたが、文字数が足りなくなったためにUTF-16では4byte(2文字)で20bit(1024*1024=1,047,576)の範囲を表すように修正されました。これをサロゲートペアといいます。
Unicodeでは5~6桁の16進数で表現しておりこれを2byteの文字の空いた領域に上下(1文字目,2文字目)にそれぞれを配置しています。
配置方法は21bitの文字コードから0x10000を差し引きその答えを上下10bitずつに分割して上下に配置し、上位には0xd800を下位には0xdc00を加算します。
よくサロゲートの説明に出される文字コードを記載しています。
文字が表示できない環境を考慮して文字を画像化したものを併記しています。
Htmlで直接文字コードで記述する場合は&#x29e3dの様に記述すると𩸽と表示されます。
下が長いつちよし
吉野屋もこの字 U+20bb7
𠮷
魚辺に花と書いて
ホッケ U+29e3d
𩸽
龍が4個で画数64
現在のUnicodeでおそらく最大画数の漢字 U+2a6a5
𪚥
U+1f600~U+1f60f
絵文字の一部

😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏
サロゲートペアでは2文字分のコードを使って1文字を表現していますので、JavaScriptの各関数がサロゲート1文字を2文字と判断して予期しない動作をしますので注意が必要です。

サロゲートペア文字の一覧

以下のテキストボックスに4~5桁の16進数を入力して表示をクリックするとサロゲート領域も含めて文字一覧を表示します。
またはコンボボックスから表示する先頭文字コードを選択することができます。
表中にカーソルを移動させると該当するセルの文字が拡大されて表の上に表示されます。()内はUTF-16のコードです。


ボタンを押す前
U+0123456789abcdef
20000 𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏
20010 𠀐𠀑𠀒𠀓𠀔𠀕𠀖𠀗𠀘𠀙𠀚𠀛𠀜𠀝𠀞𠀟
20020 𠀠𠀡𠀢𠀣𠀤𠀥𠀦𠀧𠀨𠀩𠀪𠀫𠀬𠀭𠀮𠀯
20030 𠀰𠀱𠀲𠀳𠀴𠀵𠀶𠀷𠀸𠀹𠀺𠀻𠀼𠀽𠀾𠀿
20040 𠁀𠁁𠁂𠁃𠁄𠁅𠁆𠁇𠁈𠁉𠁊𠁋𠁌𠁍𠁎𠁏
20050 𠁐𠁑𠁒𠁓𠁔𠁕𠁖𠁗𠁘𠁙𠁚𠁛𠁜𠁝𠁞𠁟
20060 𠁠𠁡𠁢𠁣𠁤𠁥𠁦𠁧𠁨𠁩𠁪𠁫𠁬𠁭𠁮𠁯
20070 𠁰𠁱𠁲𠁳𠁴𠁵𠁶𠁷𠁸𠁹𠁺𠁻𠁼𠁽𠁾𠁿
20080 𠂀𠂁𠂂𠂃𠂄𠂅𠂆𠂇𠂈𠂉𠂊𠂋𠂌𠂍𠂎𠂏
20090 𠂐𠂑𠂒𠂓𠂔𠂕𠂖𠂗𠂘𠂙𠂚𠂛𠂜𠂝𠂞𠂟
200a0 𠂠𠂡𠂢𠂣𠂤𠂥𠂦𠂧𠂨𠂩𠂪𠂫𠂬𠂭𠂮𠂯
200b0 𠂰𠂱𠂲𠂳𠂴𠂵𠂶𠂷𠂸𠂹𠂺𠂻𠂼𠂽𠂾𠂿
200c0 𠃀𠃁𠃂𠃃𠃄𠃅𠃆𠃇𠃈𠃉𠃊𠃋𠃌𠃍𠃎𠃏
200d0 𠃐𠃑𠃒𠃓𠃔𠃕𠃖𠃗𠃘𠃙𠃚𠃛𠃜𠃝𠃞𠃟
200e0 𠃠𠃡𠃢𠃣𠃤𠃥𠃦𠃧𠃨𠃩𠃪𠃫𠃬𠃭𠃮𠃯
200f0 𠃰𠃱𠃲𠃳𠃴𠃵𠃶𠃷𠃸𠃹𠃺𠃻𠃼𠃽𠃾𠃿
20100 𠄀𠄁𠄂𠄃𠄄𠄅𠄆𠄇𠄈𠄉𠄊𠄋𠄌𠄍𠄎𠄏
20110 𠄐𠄑𠄒𠄓𠄔𠄕𠄖𠄗𠄘𠄙𠄚𠄛𠄜𠄝𠄞𠄟
20120 𠄠𠄡𠄢𠄣𠄤𠄥𠄦𠄧𠄨𠄩𠄪𠄫𠄬𠄭𠄮𠄯
20130 𠄰𠄱𠄲𠄳𠄴𠄵𠄶𠄷𠄸𠄹𠄺𠄻𠄼𠄽𠄾𠄿
20140 𠅀𠅁𠅂𠅃𠅄𠅅𠅆𠅇𠅈𠅉𠅊𠅋𠅌𠅍𠅎𠅏
20150 𠅐𠅑𠅒𠅓𠅔𠅕𠅖𠅗𠅘𠅙𠅚𠅛𠅜𠅝𠅞𠅟
20160 𠅠𠅡𠅢𠅣𠅤𠅥𠅦𠅧𠅨𠅩𠅪𠅫𠅬𠅭𠅮𠅯
20170 𠅰𠅱𠅲𠅳𠅴𠅵𠅶𠅷𠅸𠅹𠅺𠅻𠅼𠅽𠅾𠅿
20180 𠆀𠆁𠆂𠆃𠆄𠆅𠆆𠆇𠆈𠆉𠆊𠆋𠆌𠆍𠆎𠆏
20190 𠆐𠆑𠆒𠆓𠆔𠆕𠆖𠆗𠆘𠆙𠆚𠆛𠆜𠆝𠆞𠆟
201a0 𠆠𠆡𠆢𠆣𠆤𠆥𠆦𠆧𠆨𠆩𠆪𠆫𠆬𠆭𠆮𠆯
201b0 𠆰𠆱𠆲𠆳𠆴𠆵𠆶𠆷𠆸𠆹𠆺𠆻𠆼𠆽𠆾𠆿
201c0 𠇀𠇁𠇂𠇃𠇄𠇅𠇆𠇇𠇈𠇉𠇊𠇋𠇌𠇍𠇎𠇏
201d0 𠇐𠇑𠇒𠇓𠇔𠇕𠇖𠇗𠇘𠇙𠇚𠇛𠇜𠇝𠇞𠇟
201e0 𠇠𠇡𠇢𠇣𠇤𠇥𠇦𠇧𠇨𠇩𠇪𠇫𠇬𠇭𠇮𠇯
201f0 𠇰𠇱𠇲𠇳𠇴𠇵𠇶𠇷𠇸𠇹𠇺𠇻𠇼𠇽𠇾𠇿
20200 𠈀𠈁𠈂𠈃𠈄𠈅𠈆𠈇𠈈𠈉𠈊𠈋𠈌𠈍𠈎𠈏
20210 𠈐𠈑𠈒𠈓𠈔𠈕𠈖𠈗𠈘𠈙𠈚𠈛𠈜𠈝𠈞𠈟
20220 𠈠𠈡𠈢𠈣𠈤𠈥𠈦𠈧𠈨𠈩𠈪𠈫𠈬𠈭𠈮𠈯
20230 𠈰𠈱𠈲𠈳𠈴𠈵𠈶𠈷𠈸𠈹𠈺𠈻𠈼𠈽𠈾𠈿
20240 𠉀𠉁𠉂𠉃𠉄𠉅𠉆𠉇𠉈𠉉𠉊𠉋𠉌𠉍𠉎𠉏
20250 𠉐𠉑𠉒𠉓𠉔𠉕𠉖𠉗𠉘𠉙𠉚𠉛𠉜𠉝𠉞𠉟
20260 𠉠𠉡𠉢𠉣𠉤𠉥𠉦𠉧𠉨𠉩𠉪𠉫𠉬𠉭𠉮𠉯
20270 𠉰𠉱𠉲𠉳𠉴𠉵𠉶𠉷𠉸𠉹𠉺𠉻𠉼𠉽𠉾𠉿
20280 𠊀𠊁𠊂𠊃𠊄𠊅𠊆𠊇𠊈𠊉𠊊𠊋𠊌𠊍𠊎𠊏
20290 𠊐𠊑𠊒𠊓𠊔𠊕𠊖𠊗𠊘𠊙𠊚𠊛𠊜𠊝𠊞𠊟
202a0 𠊠𠊡𠊢𠊣𠊤𠊥𠊦𠊧𠊨𠊩𠊪𠊫𠊬𠊭𠊮𠊯
202b0 𠊰𠊱𠊲𠊳𠊴𠊵𠊶𠊷𠊸𠊹𠊺𠊻𠊼𠊽𠊾𠊿
202c0 𠋀𠋁𠋂𠋃𠋄𠋅𠋆𠋇𠋈𠋉𠋊𠋋𠋌𠋍𠋎𠋏
202d0 𠋐𠋑𠋒𠋓𠋔𠋕𠋖𠋗𠋘𠋙𠋚𠋛𠋜𠋝𠋞𠋟
202e0 𠋠𠋡𠋢𠋣𠋤𠋥𠋦𠋧𠋨𠋩𠋪𠋫𠋬𠋭𠋮𠋯
202f0 𠋰𠋱𠋲𠋳𠋴𠋵𠋶𠋷𠋸𠋹𠋺𠋻𠋼𠋽𠋾𠋿
20300 𠌀𠌁𠌂𠌃𠌄𠌅𠌆𠌇𠌈𠌉𠌊𠌋𠌌𠌍𠌎𠌏
20310 𠌐𠌑𠌒𠌓𠌔𠌕𠌖𠌗𠌘𠌙𠌚𠌛𠌜𠌝𠌞𠌟
20320 𠌠𠌡𠌢𠌣𠌤𠌥𠌦𠌧𠌨𠌩𠌪𠌫𠌬𠌭𠌮𠌯
20330 𠌰𠌱𠌲𠌳𠌴𠌵𠌶𠌷𠌸𠌹𠌺𠌻𠌼𠌽𠌾𠌿
20340 𠍀𠍁𠍂𠍃𠍄𠍅𠍆𠍇𠍈𠍉𠍊𠍋𠍌𠍍𠍎𠍏
20350 𠍐𠍑𠍒𠍓𠍔𠍕𠍖𠍗𠍘𠍙𠍚𠍛𠍜𠍝𠍞𠍟
20360 𠍠𠍡𠍢𠍣𠍤𠍥𠍦𠍧𠍨𠍩𠍪𠍫𠍬𠍭𠍮𠍯
20370 𠍰𠍱𠍲𠍳𠍴𠍵𠍶𠍷𠍸𠍹𠍺𠍻𠍼𠍽𠍾𠍿
20380 𠎀𠎁𠎂𠎃𠎄𠎅𠎆𠎇𠎈𠎉𠎊𠎋𠎌𠎍𠎎𠎏
20390 𠎐𠎑𠎒𠎓𠎔𠎕𠎖𠎗𠎘𠎙𠎚𠎛𠎜𠎝𠎞𠎟
203a0 𠎠𠎡𠎢𠎣𠎤𠎥𠎦𠎧𠎨𠎩𠎪𠎫𠎬𠎭𠎮𠎯
203b0 𠎰𠎱𠎲𠎳𠎴𠎵𠎶𠎷𠎸𠎹𠎺𠎻𠎼𠎽𠎾𠎿
203c0 𠏀𠏁𠏂𠏃𠏄𠏅𠏆𠏇𠏈𠏉𠏊𠏋𠏌𠏍𠏎𠏏
203d0 𠏐𠏑𠏒𠏓𠏔𠏕𠏖𠏗𠏘𠏙𠏚𠏛𠏜𠏝𠏞𠏟
203e0 𠏠𠏡𠏢𠏣𠏤𠏥𠏦𠏧𠏨𠏩𠏪𠏫𠏬𠏭𠏮𠏯
203f0 𠏰𠏱𠏲𠏳𠏴𠏵𠏶𠏷𠏸𠏹𠏺𠏻𠏼𠏽𠏾𠏿
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript">
var wlen=16;
var hlen=1024/16;
var cbase;
// サロゲート文字を返す。
function schg(code){
var t;
if(0x10000<=code){
if(0x10ffff>=code){
t=code-0x10000;
var h=0xd800 | (t>>10);
var l=0xdc00 | (t &amp; 0x3ff);
return String.fromCharCode(h,l);
}else
return "";
}else
return String.fromCharCode(code);

}
// サロゲートを5桁に変換
function schg2(h,l){
var h=h &amp; 0x3ff;
var l=l &amp; 0x3ff;
var u=h<<10+l;
var u=u+0x10000;
return u;
}
function tbl_clr(){
var tbl=document.getElementById('id9');
var row=tbl.rows;
while(row.length)
tbl.deleteRow(0);
}
function tbl_make(){
var tbl=document.getElementById('id9');
var x,y;
var row,cell;
row=tbl.insertRow(-1);
cell=row.insertCell(-1);
cell.innerText="U+"
for(x=0;x<wlen;x++){
cell=row.insertCell(-1);
cell.innerText=x.toString(16);
}
for(y=0;y<wlen*hlen/wlen;y++){
row=tbl.insertRow(-1);
cell=row.insertCell(-1);
for(x=0;x<wlen;x++){
cell=row.insertCell(-1);
cell.onmouseover=function(){
mouseEvent(this);
}
}
}
}
function cput(){
var c=parseInt(document.test3Form.name3.value,16);
cbase=c=c &amp; 0x1ffff0;
var tbl=document.getElementById('id9');
if(tbl.rows.length==0){
tbl_make();
}
var x,y;
var row,cell;
for(y=0;y<wlen*hlen/wlen;y++){
row=tbl.rows[y+1];
cell=row.cells;
if(c<0x10ffff)
cell[0].innerText=c.toString(16)+" ";
else
cell[0].innerText=" ";
for(x=0;x<wlen;x++){
cell[x+1].innerText=schg(c++);
}
}
}
function cdown(){
var c=parseInt(document.test3Form.name3.value,16);
c=c-wlen*hlen;
if(c<0)
c=0;
document.test3Form.name3.value=c.toString(16);
cput();
}
function cup(){
var c=parseInt(document.test3Form.name3.value,16);
c=c+wlen*hlen;
if(0x10ffff<c)
c=0x10ffff;
document.test3Form.name3.value=c.toString(16);
cput();
}
function wset(w){
wlen=w;
tbl_clr();
cput();
}
function hset(h){
hlen=h;
tbl_clr();
cput();
}
function mouseEvent(cell){
var rnum=cell.parentNode.rowIndex;
var cnum=cell.cellIndex;
var o=document.getElementById('id8');
var c=cbase+(rnum-1)*wlen+cnum-1;
if(0x10000<=c){
var u=c-0x10000;
var h=0xd800 | (u>>10);
var l=0xdc00 | (u &amp; 0x3ff);
var u16="("+h.toString(16)+","+l.toString(16)+") ";
o.innerHTML="U+"+c.toString(16)+u16+"<span class='BIGFONT'>"+cell.innerText+"</span>";
}else
o.innerHTML="U+"+c.toString(16)+"<span class='BIGFONT'>"+cell.innerText+"</span>";

}
</script>
<form name="test3Form">
<input type="text" size="8" value="20000" name="name3" />
<input type="button" value="表示" onclick="cput()" />
<select name="name4" id="id11" onchange="selchg()">
</select>
<br />
<input type="button" value="←" onclick="cdown()" />
<input type="button" value="→" onclick="cup()" />
<input type="button" value="横16文字" onclick="wset(16)" />
<input type="button" value="横32文字" onclick="wset(32)" />
<input type="button" value="横64文字" onclick="wset(64)" />
<input type="button" value="縦16文字" onclick="hset(16)" />
<input type="button" value="縦32文字" onclick="hset(32)" />
<input type="button" value="縦64文字" onclick="hset(64)" />
<input type="button" value="縦128文字" onclick="hset(128)" />
</form>
<br />
<span id="id8">ボタンを押す前</span>
<style type="text/css">
table.TBL{
border-collapse: collapse;
border-spacing: 0px 0px;
cellspacing: 0;
}
table.TBL td{
padding:0px;
text-align: center;
vertical-align: middle;
}

</style>


<div class="hascroll"><table id="id9" class="TBL"></table></div>
<form name="test4Form">
<input type="button" value="←" onclick="cdown()" />
<input type="button" value="→" onclick="cup()" />
<input type="button" value="横16文字" onclick="wset(16)" />
<input type="button" value="横32文字" onclick="wset(32)" />
<input type="button" value="横64文字" onclick="wset(64)" />
<input type="button" value="縦16文字" onclick="hset(16)" />
<input type="button" value="縦32文字" onclick="hset(32)" />
<input type="button" value="縦64文字" onclick="hset(64)" />
<input type="button" value="縦128文字" onclick="hset(128)" />
</form>
</body>
</html>