<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="1" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[1]</anchor-end> <dfn><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor></dfn> は、小さな (少ない) <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">集合</anchor>によってより大きな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">集合</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>を表現するための<ruby><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor><rt>アルゴリズム</rt></ruby>です <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal></src>。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>を特定の値に固定した<ruby><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">実現値</anchor><rt>インスタンス</rt></ruby> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プロファイル</anchor>)
として <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> があり、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">IDNA</anchor> で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">国際化ドメイン名</anchor>のために使われています。</p><section><h1>仕様書</h1><refs xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><ul xmlns="http://www.w3.org/1999/xhtml"><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[2]</anchor-end> <cite xml:lang="en">RFC 3492 - Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)</cite> 
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://tools.ietf.org/html/rfc3492">http://tools.ietf.org/html/rfc3492</anchor-external></li></ul></refs></section><section><h1>性質</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="3" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[3]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> は次の性質を持つように設計されています <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 1.1</src>。</p><figure class="list"><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="4" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[4]</anchor-end> <rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>完全性</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">completeness</rt></rubyb>:
あらゆる<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>拡張文字列</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">extended string</rt></rubyb> (任意の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の列) は、
<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>基本文字列</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">basic string</rt></rubyb> (<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>基本符号位置</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">basic code point</rt></rubyb>の列)
によって表現できます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="5" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[5]</anchor-end> <rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>固有性</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">uniqueness</rt></rubyb>: ある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>を表現する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>は、
高々1つしか存在しません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="6" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[6]</anchor-end> <rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>可逆性</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">reversibility</rt></rubyb>: <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">写像</anchor>できたとすると、
その<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>から元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>に再変換することができます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="7" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[7]</anchor-end> <rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>効率的符号化</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">efficient encoding</rt></rubyb>: <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>の長さと<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>の長さの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">比</anchor>は小さいです。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="8" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[8]</anchor-end> <rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>単純性</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">simplicity</rt></rubyb>: <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>は十分単純です。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="10" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[10]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">効率性</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">単純性</anchor>は必ずしも両立しませんが、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> 
は両者のバランスがとれたものを目指しています。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="9" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[9]</anchor-end> <rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>可読性</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">readability</rt></rubyb>: <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>中の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>は、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>中にそのまま出てきます。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="11" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[11]</anchor-end> といってもその主目的は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">効率性</anchor>なのですが。</li></ul></li></ul></figure></section><section><h1>構成要素</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="302" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[302]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> では、<figure class="list"><ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置分居</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;17</anchor-internal>)</li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">挿入非整列符号化</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="20" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;20</anchor-internal>)</li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;22</anchor-internal>)</li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">偏差適応</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;56</anchor-internal>)</li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字・小文字混合注釈</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="322" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;322</anchor-internal>) </li></ul></figure>... といった手法を組み合わせて使っています。</p><section><h1>基本符号位置分居</h1><section><h1>符号化</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="13" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[13]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>を <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>する時には、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>はすべて元々の順序でそのまま<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>の先頭に含めます。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.1</src></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="14" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[14]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>を並べた後には<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>を置きます。
(<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>がまったく無いときは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>は含めません。)
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>は特定の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>とし、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>のその後の部分には使わないものとします。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.1</src></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[17]</anchor-end> これを<dfn><rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置分居<rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">basic code point segregation</rt></rubyb></dfn>と呼びます。</p></section><section><h1>復号</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="15" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[15]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号器</anchor>は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>中の最後の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>を探すことにより、
どこまでが<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>を並べたものでどこからが非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>を表すものか判断できます。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.1</src></p></section><section><h1>例</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="16" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[16]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> での例: 「abcあいうえおxyz」は、<pre class="code">abcxyz-k43eqasuw</pre>... となります。<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>で表せる部分が「abcxyz」で、
その後に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>として「<code class="char"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">-</anchor></code>」が挟まり、
最後に「あいうえお」を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>した文字列が続きます。</p></section></section><section><h1>挿入非整列符号化</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="18" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[18]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>と <code class="char"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">-</anchor></code> を取って残った部分は非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>を表しています。
これは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>を使った<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">非負整数</anchor>として表された<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の列となっています。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.2</src></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="19" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[19]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号器</anchor>の仕事は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の列にこの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の列を適用して元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>に戻すことであり、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化器</anchor>の仕事はそうなるような<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の列を生成することとなります。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="20" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[20]</anchor-end> この符号化の方式は<dfn><rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>挿入非整列符号化</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">insertion unsort coding</rt></rubyb></dfn>と呼ばれています。</p><section><h1>復号</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="21" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[21]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>の手順をおおまかに表すと次のようになります <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.2</src>。<figure class="steps"><ol><li>まず、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>の最初の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の部分を取り出します。</li><li>次に、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>の後の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の列から<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>を1つずつ取出し、それを適用します。<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>1つに対して1つの非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が挿入されることになります。<ul><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の列は、「先へと進む回数を表す値」と「挿入する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を表す値」が交互に繰り返される<rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>連長符号化</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">run-length encoding</rt></rubyb>になっています。</li><li><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が挿入されるとしたら、それは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">誤り</anchor>です。</li></ul></li></ol></figure></p></section></section><section><h1>一般化可変長整数</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[22]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>の列として表されるのですが、通常の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>だと、<figure class="list"><ul><li>先頭に「0」を付けると同じ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>を表す別の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>が作れてしまう</li><li>複数の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>を並べると (1つの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁数</anchor>の情報が別途与えられないと) どこで区切られるかわからない</li></ul></figure>... といった問題があるため、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> ではこれらの問題を解消した<dfn><rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数<rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">generalized variable-length integers</rt></rubyb></dfn>を使います。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="23" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[23]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>としては <code class="math">0</code> ... <code class="math"><var xml:lang="en">base</var> - 1</code> を使います。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="24" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[24]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> <code class="math"><var>t</var> (<var>j</var>)</code> を使います。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src><ul><li>一番上の桁が <var>j</var> 番目とすると、その桁だけが <code class="math"><var>digit<sub><var>j</var></sub></var> &lt; <var>t</var> (<var>j</var>)</code> を満たすとします。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src><ul><li>続きがもうない桁 <var>j</var> では <code class="math">0</code> ... <code class="math"><var>t</var> (<var>j</var>) - 1</code> を使います。</li><li>続きがまだある桁 <var>j</var> では <code class="math"><var>t</var> (<var>j</var>)</code> ... <code class="math"><var xml:lang="en">base</var> - 1</code> を使います。</li></ul></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="25" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[25]</anchor-end> この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字列</anchor>によって表される値は、次の <code class="math"><var>w</var> (<var>j</var>)</code> を使って <code class="math">Σ<var>j</var> <var>digit<sub><var>j</var></sub></var> × <var>w</var> (<var>j</var>)</code> で得られる値です。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src><ul><li><code class="math"><var>w</var> (0) = 1</code> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src><ul><li>つまり、一番下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>については、重みは 1 であり、表される値はその<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の値と同じです。</li></ul></li><li><code class="math"><var>w</var> (<var>j</var>) = <var>w</var> (<var>j</var> - 1) × (<var>base</var> - <var>t</var> (<var>j</var> - 1))</code> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src><ul><li>それより上の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>については、重みは一つ下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の重みと一つ下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>で続きがまだある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>に使える<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の個数の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">積</anchor>です。</li><li>ここで <code class="math"><var>t</var> (<var>j</var> - 1) = 0</code> だったとすると、通常の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>と同じになります。 (もちろん、その場合 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="24" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;24</anchor-internal> の「続きがもうない桁」が該当無しになり、続きがあるかどうかは判定できなくなります。</li></ul></li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="49" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[49]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> では<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小エンディアン</anchor>を使います <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src>。つまり、
一番下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>が最初に来て、一番上の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>よりも小さな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>)
が最後に来ます。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="48" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[48]</anchor-end> <code class="math"><var>t</var> (<var>j</var>)</code> をどう決めても、
任意の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">非負整数</anchor>の値について<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>がちょうど1つだけ存在します。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="50" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[50]</anchor-end> 実際には <code class="math"><var>t</var> (<var>j</var>)</code> は<figure class="list"><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="51" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[51]</anchor-end> <code class="math"><var>t</var> (<var>j</var>) = <var>base</var> × (<var>j</var> + 1) - <var>bias</var></code></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="52" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[52]</anchor-end> ただし <var>t<sub>min</sub></var> より小さな値とはしない</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="53" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[53]</anchor-end> ただし <var>t<sub>max</sub></var> より大きな値とはしない</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="54" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[54]</anchor-end> <var>base</var>, <var>t<sub>min</sub></var>, <var>t<sub>max</sub></var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">定数</anchor></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="55" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[55]</anchor-end> <var>bias</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">状態変数</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;56</anchor-internal>)</li></ul></figure>... と定義します。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src></p><section><h1>符号化</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="37" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[37]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>、つまりある値を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>で表現するには、次のようにします
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src>。</p><figure class="steps"><ol><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="38" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[38]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>する値を <var>N</var> とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="41" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[41]</anchor-end> <var>t</var> を <code class="math"><var>t</var> (0)</code> とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="39" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[39]</anchor-end> <var>N</var> が <var>t</var> よりも小さければ、 <var>N</var> を表す<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>を出力し、停止します。ここまでに出力した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>した結果です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="42" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[42]</anchor-end> そうでなければ、<ol><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="43" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[43]</anchor-end> <code class="math"><var>t</var> + ((<var>N</var> - <var>t</var>) mod (<var>base</var> - <var>t</var>))</code> を表す<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>を出力します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="46" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[46]</anchor-end> <var>N</var> を <code class="math">(<var>N</var> - <var>t</var>) div (<var>base</var> - <var>t</var>)</code> とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="44" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[44]</anchor-end> <var>t</var> を次の桁の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="45" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[45]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="39" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;39</anchor-internal> に戻ります。</li></ol></li></ol></figure><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="47" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[47]</anchor-end> つまり、最後の桁では表したい値そのものに対応する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>よりも小さな値)
を使って表し、それ以外の桁では<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>よりも小さな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>を除いた残った<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>だけで
(通常の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>のように) 表そうとしたときに使う<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>を使って表す、ということになります。</p></section><section><h1>復号</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="26" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[26]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>、つまり<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>の表す値の計算の方法は、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="25" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;25</anchor-internal> から自然に定まります。</p><figure class="steps"><figcaption><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="28" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[28]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.3</src></figcaption><ol><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="27" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[27]</anchor-end> <var>N</var> を 0 とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="29" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[29]</anchor-end> <var>w</var> を 1 とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="40" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[40]</anchor-end> <var>t</var> を <code class="math"><var>t</var> (0)</code> とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="30" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[30]</anchor-end> <var>d</var> を次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="31" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[31]</anchor-end> <var>d</var> と <var>w</var> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">積</anchor>を <var>N</var> に足します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="32" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[32]</anchor-end> <var>d</var> が <var>t</var> よりも小さければ、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">停止</anchor>します。 <var>N</var> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>結果の値です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="33" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[33]</anchor-end> そうでなければ、<ol><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="34" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[34]</anchor-end> <var>w</var> に <var>base</var> から <var>t</var> を引いた値を掛けます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="35" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[35]</anchor-end> <var>t</var> を次の桁の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="36" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[36]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="30" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;30</anchor-internal> に戻ります。</li></ol></li></ol></figure></section></section><section><h1>偏差適応</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[56]</anchor-end> <var>bias</var> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="55" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;55</anchor-internal>) は、<dfn><rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">偏差適応<rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">bias adaptation</rt></rubyb></dfn>によって、
一つ前の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の値に依存して決定します。
具体的には、前の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の後、次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の処理の前に、次のように計算します <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src>。</p><figure class="steps"><ol><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="60" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[60]</anchor-end> <var>delta</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>とします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="57" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[57]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="58" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;58</anchor-internal> での<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>を防ぐために <var>delta</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数除算</anchor>します。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src><ul><li>最初の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>であるなら、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">定数</anchor> <var>damp</var> で割ります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src></li><li>2つ目以降の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>であるなら、2 で割ります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src></li><li>通常1つ目の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>よりも2つ目の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の方が小さいため、こうしています。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="58" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[58]</anchor-end> <var>delta</var> に、そこまでに<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>または<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor> <weak xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(その<anchor>差分</anchor>に対応する<anchor>符号位置</anchor>や<anchor>基本符号位置</anchor>もすべて含みます。)</weak> の長さによって<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数除算</anchor>した結果を足し合わせます。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src><ul><li>次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>はより長い文字列に挿入されることとなるので、こうしています。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src></li><li>つまり、文字列の長さに対する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の長さの割合を <var>delta</var> に足すことになります。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="59" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[59]</anchor-end> <var>delta</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>の範囲に収まるまで割り続けます。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src><ul><li>これは次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>を表現するのに必要な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の最小の個数を予想するものとなります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src></li><li>具体的には、 <code>while delta &gt; ((base - tmin) * tmax) div 2 do let delta = delta div (base - tmin)</code> とします。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src></li><li><var>base</var> から <var>t<sub>min</sub></var> を引くと、続きがまだあることを表す<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>が最も多いときの個数となります。</li><li><var>t<sub>max</sub></var> は続きがもうないことを表す<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>が最も多いときの個数となります。</li><li>ループの条件部の <code class="math">(<var>base</var> - <var>t<sub>min</sub></var>) × <var>t<sub>max</sub></var>)</code> では、まだ続く数字の個数ともう続かない数字の個数をかけているので、ちょうど2桁で表せる最大の値を求めていることになります。</li><li>つまり、このループで <var>delta</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数除算</anchor>した回数が、続きがまだある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>を最も多く取った時
<weak xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(<var xmlns="http://www.w3.org/1999/xhtml">t<sub>min</sub></var> を<anchor>閾値</anchor>としたとき)</weak> の桁数になります。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="61" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[61]</anchor-end> <var>bias</var> は、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="59" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;59</anchor-internal> で除算した回数と <var>base</var> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">積</anchor>に対して、
<code>((base - tmin + 1) * delta) div (delta + skew)</code> を足した値とします。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src><ul><li>現在の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>は次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>の長さのヒントであり、それによって
<code class="math"><var>t</var> (<var>j</var>)</code> は最後になると期待される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>から上の方の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>は <var>t<sub>max</sub></var> に、
最後になると期待される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の前の前までの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>ほ <var>t<sub>min</sub></var> に、
最後になると期待される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の手前の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>はその中間となるよう、こうしています。
(最後になると期待される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>が実際には不要であるとの期待と実際にはもっと長くなる危険性とのバランスでそうしています。) <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 3.4</src></li></ul></li></ol></figure><section><h1>擬似コード</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="195" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[195]</anchor-end> 次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">擬似コード</anchor>は、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.1 に注釈を入れたものです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="196" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[196]</anchor-end> <pre class="code"> function adapt(delta,numpoints,firsttime):
     if firsttime then let delta = delta div damp
     else let delta = delta div 2</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="199" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[199]</anchor-end> 初回実行であれば<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>の <var>damp</var> を、そうでなければ 2 を使って <var>delta</var> を割ります。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="200" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[200]</anchor-end> これは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>を防止するためです。 (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;56</anchor-internal>)</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="209" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[209]</anchor-end> 1つ目の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>は最初の <var>n</var> (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> では <var>0x80</var>) からの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>が <var>delta</var> に反映されているので、通常は大きな値になります。2つ目以降では <weak xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(同じ<anchor>書字方式</anchor>の<anchor>文字</anchor>は近い<anchor>符号位置</anchor>を持つ可能性が高いという性質を仮定すると)</weak> 小さな値となります。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="198" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[198]</anchor-end> <pre class="code">     let delta = delta + (delta div numpoints)</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="210" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[210]</anchor-end> <var>numpoints</var> は処理済みの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数です。 <var>delta</var> は前の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>から今回の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>までの値の差に処理済みの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数を掛けている (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="78" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;78</anchor-internal>) ので、ここで足している値はその値の差を何分の一かにしたもの (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="199" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;199</anchor-internal>) といえます。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="211" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[211]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>は後から出てくるものほど文字列のより後ろの方へと挿入されて <var>delta</var> が大きくなる傾向にあるので (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="128" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;128</anchor-internal> 参照)、その補正のために足しています。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="201" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[201]</anchor-end> <pre class="code">     let k = 0
     while delta &gt; ((base - tmin) * tmax) div 2 do begin
       let delta = delta div (base - tmin)
       let k = k + base
     end</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="213" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[213]</anchor-end> <var>delta</var> をできるだけ割ります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="214" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[214]</anchor-end> <var>base</var> から <var>t<sub>min</sub></var> を引いた数は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> <var>t</var> をもっとも小さくし、できるだけ次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>に続くことを意味する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>を増やした時の次に続く<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の個数を表しています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="215" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[215]</anchor-end> そのたびに <var>k</var> に <var>base</var> を足していっているので、 <var>k</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の述べ個数になります。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="216" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[216]</anchor-end> このあたりは <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="157" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;157</anchor-internal> のループに対応しています。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="217" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[217]</anchor-end> ループ条件にある <code class="math">(<var>base</var> - <var>t<var>min</var></var>) × <var>t<sub>max</sub></var></code> は、<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="218" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[218]</anchor-end> 前半は <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="214" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;214</anchor-internal> と同じです。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="219" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[219]</anchor-end> <var>t<sub>max</sub></var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> <var>t</var> をもっとも大きくし、できるだけ次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>に続かないことを意味する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>を増やしたときの次に続かない<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の個数を表しています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="220" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[220]</anchor-end> それらの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">積</anchor>ですから、この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>はまだ続き、次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>で最後であるとしたときに表せる値の個数になります。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="212" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[212]</anchor-end> <pre class="code">     return k + (((base - tmin + 1) * delta) div (delta + skew))</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="221" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[221]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="201" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;201</anchor-internal> で <var>delta</var> を何度も割っているので、ここでの <var>delta</var> は最後の2<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>相当の値になっています。</li></ul></section></section></section><section><h1>大文字・小文字混合注釈</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="322" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[322]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> の実質唯一の具象化であるところの <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor>
の主用途たる <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">IDNA</anchor> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字・小文字を区別しない</anchor>ことになっており、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> 化の前に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">正規化</anchor>されます。しかし、
表示用などで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>の区別を保存しておきたいことがあります。
そのため、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本文字列</anchor>には<dfn><rubyb xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:"><anchor>大文字・小文字混合注釈</anchor><rt xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">mixed-case annotation</rt></rubyb></dfn>を埋め込むことができます
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> A.</src>。</p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="323" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[323]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>については、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置分居</anchor>による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>・<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>で元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>・<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>の区別が保存されますので、特に何もすることはありません。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> A.</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="324" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[324]</anchor-end> 非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>については、 <var>delta</var> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>として<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>されますが、
その<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>を表す最後の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>・<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>の区別により元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>・<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>の区別を保存します。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> A.</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="325" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[325]</anchor-end> ただし、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号器</anchor>の出力はあくまで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>された <var>delta</var> そのものであり、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>・<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>の区別はそこでは無視されます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="326" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[326]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字・小文字混合注釈</anchor>は、通常の出力とは別に、どの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字</anchor>が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>あるいは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>であるといった情報を出力することとなります。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> A.</src></li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="327" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[327]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字・小文字混合注釈</anchor>はオプションの機能であり、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> や <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor>
の実装はこれに対応する必要はありません <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> A.</src>。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="328" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[328]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字・小文字混合注釈</anchor>を使うためには<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の選定に一定の制約があります (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="72" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;72</anchor-internal>)。</p></section><section><h1>引数</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="303" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[303]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> にはいくつかの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>があります。この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>を特定の値に固定することにより、
具体的な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>が定まります。 (その一例が <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> です。)</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="62" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[62]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>には、次の制約があります <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src>。</p><figure class="list"><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="63" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[63]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>のうちの1つは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>とする必要があります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="64" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[64]</anchor-end> <var xml:lang="en">base</var> を残った<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の数より大きくはできません。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="65" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[65]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>以外の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>に対して 0 ... <code class="math"><var>base</var> - 1</code> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の値を割り当てる必要があります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="66" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[66]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>のように、複数の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>が同じ値を持っても構いません。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="72" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[72]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字・小文字混合注釈</anchor>を使いたい場合、 0 ... <code class="math"><var>t<sub>max</sub></var> - 1</code> のすべての値について<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">小文字</anchor>が必要です。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="67" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[67]</anchor-end> <var>initial<sub><var>n</var></sub></var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">拡張文字列</anchor>に現れる最小の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>より大きな値にはできません。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="149" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[149]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;94</anchor-internal> での処理がこの初期値からはじまるので、これより小さな非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が存在すると、取りこぼしておかしな結果になってしまいます。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="68" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[68]</anchor-end> <code class="math">0 ≦ <var>t<sub>min</sub></var> ≦ <var>t<sub>max</sub></var> ≦ <var>base</var> - 1</code> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="69" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[69]</anchor-end> <code class="math">1 ≦ <var>skew</var></code> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="70" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[70]</anchor-end> <code class="math">1 ≦ <var>damp</var></code> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="71" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[71]</anchor-end> <code class="math"><var>initial<sub>bias</sub></var> mod <var>base</var> ≦ <var>base</var> - <var>t<sub>min</sub></var></code> <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 4.</src></li></ul></figure></section><section><h1>符号化</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="73" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[73]</anchor-end> 次に示すのは、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3 に示された<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">擬似コード</anchor>による <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>の実装に適宜注釈を入れたものです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="110" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[110]</anchor-end> <pre class="code">   let n = initial_n</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="111" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[111]</anchor-end> <var>n</var> は、次に処理するべき非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>は <var>n</var> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以上</anchor>で最小のものである、というような値を保持する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">変数</anchor>です。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="112" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[112]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> では <var>initial<sub><var>n</var></sub></var> は <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">0x80</anchor> です。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">0x00</anchor> ... <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">0x7F</anchor> はすべて<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>であるため、最初に処理するべき非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>として最小足り得る <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">0x80</anchor> に設定されています。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="109" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[109]</anchor-end> <pre class="code">   let delta = 0</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="141" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[141]</anchor-end> <var>delta</var> は非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>に直接関わる値です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="142" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[142]</anchor-end> ここでは初期値を設定しているだけです。 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="78" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;78</anchor-internal> で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>される値が決定します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="143" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[143]</anchor-end> 他に <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="128" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;128</anchor-internal> と <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="119" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;119</anchor-internal> でも値が変化します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="140" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[140]</anchor-end> <pre class="code">   let bias = initial_bias</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="202" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[202]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>の決定 (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="153" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;153</anchor-internal>) に使う偏差の初期値を設定しています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="203" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[203]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="104" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;104</anchor-internal> で前の <var>delta</var> に基づき次の <var>delta</var> のための <var>bias</var> を決定します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="177" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[177]</anchor-end> <pre class="code">   let h = b = the number of basic code points in the input</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="105" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[105]</anchor-end> <var>b</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の数を表し、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="98" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;98</anchor-internal> と <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="104" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;104</anchor-internal> で参照されています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="107" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[107]</anchor-end> <var>h</var> は処理し終わった<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数を表します。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="134" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[134]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="98" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;98</anchor-internal> で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の処理が終わるので、 <var>h</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の個数としておきます。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="98" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[98]</anchor-end> <pre class="code">   copy them to the output in order, followed by a delimiter if b &gt; 0</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="103" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[103]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置分居</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;17</anchor-internal>) を行います。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="99" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[99]</anchor-end> <var xml:lang="en">input</var> から<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>を取出し、そのままの順序で <var>output</var> に複写します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="100" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[100]</anchor-end> その後に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>を出力します。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="101" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[101]</anchor-end> ただし、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="99" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;99</anchor-internal> が無かったときは出力しません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="102" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[102]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> では「<code class="char"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">-</anchor></code>」が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>です。</li></ul></li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="74" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[74]</anchor-end> <pre class="code">   {if the input contains a non-basic code point &lt; n then fail}</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="106" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[106]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;94</anchor-internal> で非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>を <var>n</var> から上へと探していくので、 <var>n</var> 未満の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が含まれているとすると、正しく処理できません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="76" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[76]</anchor-end> このチェックは、 <var>initial<sub><var>n</var></sub></var> より小さな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>がすべて<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>なら、省略できます。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="77" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[77]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> ではこれが成立します。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src></li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="75" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[75]</anchor-end> <pre class="code">   while h &lt; length(input) do begin</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="108" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[108]</anchor-end> <var>h</var> は処理し終わった<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数になっているので、 <var>input</var> のすべての<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を処理するまでこのループは続きます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[94]</anchor-end> <pre class="code">     let m = the minimum {non-basic} code point &gt;= n in the input</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="113" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[113]</anchor-end> <var>m</var> はこのループで処理する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を表しています。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="114" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[114]</anchor-end> <var>n</var> が次に処理するべきかもしれない最小の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>となっており、それ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以上</anchor>であって <var>input</var> に含まれている最小の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が実際に処理されるべき対象となります。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="79" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[79]</anchor-end> 「非基本」という条件は、すべての<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>よりも <var>initial<sub><var>n</var></sub></var> が大きければ、ここで比較される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>はすべて <var>initial<sub><var>n</var></sub></var> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以上</anchor>であるため、常に成立します。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="82" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[82]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> ではこれが成立します。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="112" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;112</anchor-internal>)</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="78" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[78]</anchor-end> <pre class="code">     let delta = delta + (m - n) * (h + 1), fail on overflow</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="144" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[144]</anchor-end> ここで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>されて出力される <var>delta</var> が決まります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="145" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[145]</anchor-end> <var>delta</var> は <code class="math"><var>h</var> + 1</code> 進数で、一番下の桁が直前の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>からの位置の差 (元の <var>delta</var>)、それより上の桁が直前の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>から実際の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>までの値の差 (<code class="math"><var>m</var> - <var>n</var></code>) を表しています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="115" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[115]</anchor-end> <var>delta</var> は、この行の直前において、<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="116" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[116]</anchor-end> 初回の実行では、 0 です (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="109" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;109</anchor-internal>)。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="130" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[130]</anchor-end> 2回目以降の実行では、直前に処理した非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>からの位置の差となります。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="129" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[129]</anchor-end> 内側のループ (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;120</anchor-internal>) において、 <var>c</var> が <var>n</var> より小さい時や <var>c</var> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>であるときに<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>されます (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="128" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;128</anchor-internal>)。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="121" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[121]</anchor-end> 内側のループ (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;120</anchor-internal>) において、 <var>c</var> と <var>n</var> が等しいとき (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="80" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;80</anchor-internal>) に 0 にリセットされます (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="117" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;117</anchor-internal>)。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="127" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[127]</anchor-end> 必ず一度は実行されます (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="125" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;125</anchor-internal>)。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="123" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[123]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;120</anchor-internal> のループを抜けると、必ず <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="122" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;122</anchor-internal> を通ります。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="122" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[122]</anchor-end> 外側のループ (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="75" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;75</anchor-internal>) の末尾でインクリメントされます (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="119" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;119</anchor-internal>)。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="132" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[132]</anchor-end> まとめると、<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="131" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[131]</anchor-end> 非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が連続する場合には、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="121" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;121</anchor-internal> で 0 にリセットされ、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="122" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;122</anchor-internal> で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>されるので、 1 になります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="133" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[133]</anchor-end> 非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の後に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>や処理済みの非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>がいくつかあるときは、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="121" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;121</anchor-internal> で 0 にリセットされ、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="129" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;129</anchor-internal> で処理済み数だけ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>され、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="122" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;122</anchor-internal> で一度<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>されるので、結局 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="121" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;121</anchor-internal> で処理した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>との間にある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数より1大きい値 (つまり位置の差) となります。</li></ul></li></ul></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="135" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[135]</anchor-end> <var>delta</var> が <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="115" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;115</anchor-internal> のような値となるので、 <var>delta</var> が最大となるのはすべてが非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の時であって、その値は先頭から次に処理する<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>までの距離、つまり処理済みの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数、すなわち <var>h</var> となります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="139" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[139]</anchor-end> <code class="math"><var>m</var> - <var>n</var></code> は、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;94</anchor-internal> より、ここで処理され得る最小の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor> (<var>n</var>) と実際に <var>input</var> に含まれていた最小の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor> (<var>m</var>) との<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差</anchor>となります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="147" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[147]</anchor-end> この <var>delta</var> と <code class="math"><var>m</var> - <var>n</var></code> は、 <var>delta</var> が <code class="math"><var>h</var> + 1</code> よりも必ず小さくなるので、 <code class="math"><var>m</var> - <var>n</var></code> に <code class="math"><var>h</var> + 1</code> を掛けて足せば一つの値にできます。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="137" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[137]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>時に取り出すには、 <code class="math"><var>h</var> + 1</code> で割った<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">商</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">余り</anchor>を求めればよいのです。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="148" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[148]</anchor-end> <var>h</var> はここまでに処理した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数なので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>時にも自明です。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="89" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[89]</anchor-end> <var>input</var> が長すぎる時 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src> (元の <var>delta</var>) や非常に大きな値を含んでいるとき <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src> (<var>m</var> と <var>n</var> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差</anchor>が大きすぎるとき) に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>するおそれがあるので、チェックが必要です。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="146" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[146]</anchor-end> <code class="math"><var>h</var> + 1</code> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>することは、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="75" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;75</anchor-internal> で比較に使われる <var>input</var> の長さが<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>しないという前提より、また <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="75" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;75</anchor-internal> の条件がここまで成立していることから、あり得ません。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="88" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[88]</anchor-end> <pre class="code">     let n = m</pre></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[120]</anchor-end> <pre class="code">     for each code point c in the input (in order) do begin</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="150" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[150]</anchor-end> ここから内側のループです。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="128" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[128]</anchor-end> <pre class="code">       if c &lt; n {or c is basic} then increment delta, fail on overflow</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="151" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[151]</anchor-end> 処理対象の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor> <var>c</var> が <var>n</var> よりも小さいか、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>であるなら、つまり今回の外側のループによって処理される<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>である <var>n</var> より小さいものなら、 <var>delta</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="81" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[81]</anchor-end> <var>n</var> の初期値である <var>initial<sub><var>n</var></sub></var> があらゆる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>よりも大きいなら、 <var>c</var> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>である時も常に <code class="math"><var>c</var> &lt; <var>n</var></code> が成立しますから、チェックを省略できます。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="83" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[83]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> ではこれが成立します。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="152" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[152]</anchor-end> 内側のループ (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;120</anchor-internal>) 全体で見ると、 <var>delta</var> は結局のところ、これまでに処理を終えた<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数が <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="78" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;78</anchor-internal> に足されたものとなります。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="87" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[87]</anchor-end> <var>input</var> が長すぎる時に <var>delta</var> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>するおそれがあるので、チェックが必要です。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src></li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="80" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[80]</anchor-end> <pre class="code">       if c == n then begin</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="125" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[125]</anchor-end> この <var>n</var> は <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;94</anchor-internal> の <var>m</var> を <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="88" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;88</anchor-internal> で代入したものなので、 <var>input</var> 中にある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>です。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="126" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[126]</anchor-end> 内側のループ (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;120</anchor-internal>) は <var>input</var> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を順に処理しているので、最低1回は必ずこの条件が成立します。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="124" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[124]</anchor-end> <pre class="code">         let q = delta</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="158" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[158]</anchor-end> ここからが<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;22</anchor-internal>) による<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>です。 
<var xml:lang="en">delta</var> の値を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>して出力します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="157" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[157]</anchor-end> <pre class="code">         for k = base to infinity in steps of base do begin</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="159" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[159]</anchor-end> このループでは、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>の一番下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>から順に出力します。最後の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>まで出力したら抜けます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="156" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[156]</anchor-end> <var>k</var> は <var>base</var> の倍数で1倍、2倍、... と増えていきます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="155" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[155]</anchor-end> このループは <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="154" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;154</anchor-internal> で抜けます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="153" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[153]</anchor-end> <pre class="code">           let t = tmin if k &lt;= bias {+ tmin}, or
                   tmax if k &gt;= bias + tmax, or k - bias otherwise</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="160" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[160]</anchor-end> <var>t</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>における、現在の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>で使う<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="24" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;24</anchor-internal>) です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="86" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[86]</anchor-end> <var>k</var> から <var>bias</var> を引いた値を <var>t</var> に代入しています。ただし、 <var>t</var> が <var>t<sub>min</sub></var> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以上</anchor> <var>t<sub>max</sub></var> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以下</anchor>となるようにします。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="84" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[84]</anchor-end> <var>t<sub>min</sub></var> を足すところを省略すると、 <var>k</var> が <var>bias</var> よりも大きく <var>bias</var> と <var>t<sub>min</sub></var> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">和</anchor>よりも小さいときに誤った結果になりますが、 <var>bias</var> の計算方法および各<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>の条件より、 <var>k</var> がそのような値になることはありません。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="85" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[85]</anchor-end> これは常に成立します。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="204" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[204]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="157" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;157</anchor-internal> のループの、<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="208" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[208]</anchor-end> はじめのうちは <var>k</var> が小さいので、 <var>t<sub>min</sub></var> が使われます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="205" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[205]</anchor-end> 最後のほうでは <var>k</var> が大きいので、 <var>t<sub>max</sub></var> が使われます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="207" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[207]</anchor-end> 中間では <var>k</var> よりも <var>bias</var> の分小さな値が使われます。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="206" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[206]</anchor-end> このあたりでおかしなことが起こらないように各<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">引数</anchor>には <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="71" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;71</anchor-internal> の条件があります。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="154" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[154]</anchor-end> <pre class="code">           if q &lt; t then break</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="162" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[162]</anchor-end> <var>q</var> が <var>t</var> より小さいということは、 <var>q</var> は最後の1桁だけで表現できるので、ループを抜けます。ループを抜けた <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="163" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;163</anchor-internal> で最後の桁が出力されます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="161" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[161]</anchor-end> <pre class="code">           output the code point for digit t + ((q - t) mod (base - t))</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="164" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[164]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="154" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;154</anchor-internal> の条件が成立しなかったので、これは途中の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="165" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[165]</anchor-end> この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>で表されるのは、<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="166" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[166]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>よりも下の成分 <var>t</var> と</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="167" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[167]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>よりも上の成分 <code class="math"><var>q</var> - <var>t</var></code> のうち、<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="168" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[168]</anchor-end> この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor>よりも上の値を表すために使える<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>は <code class="math"><var>base</var> - <var>t</var></code> 個なので</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="169" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[169]</anchor-end> それで割った余り</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="170" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[170]</anchor-end> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">和</anchor>、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="166" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;166</anchor-internal> + <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="169" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;169</anchor-internal> です。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="171" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[171]</anchor-end> <pre class="code">           let q = (q - t) div (base - t)</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="173" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[173]</anchor-end> そして次以降の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>で表されるのは、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="167" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;167</anchor-internal> のうち <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="168" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;168</anchor-internal> で割った<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">商</anchor>であり、これを新しい <var>q</var> とします。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="172" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[172]</anchor-end> <pre class="code">         end</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="174" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[174]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="157" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;157</anchor-internal> に戻ります。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="163" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[163]</anchor-end> <pre class="code">         output the code point for digit q</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="175" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[175]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="154" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;154</anchor-internal> から来ました。 <var>q</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> <var>t</var> より小さく、1桁の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>で表せます。これが <var>delta</var> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>の最後の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>です。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="104" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[104]</anchor-end> <pre class="code">         let bias = adapt(delta, h + 1, test h equals b?)</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="176" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[176]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">偏差適応</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;56</anchor-internal>) により、次の <var>delta</var> のための <var>bias</var> を計算します。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="197" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[197]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">関数</anchor> <var>adapt</var> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="196" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;196</anchor-internal>) を呼び出します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="178" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[178]</anchor-end> 第1引数の <var>delta</var> はループの今周で処理した値であり、これを元に適応させた <var>bias</var> が返されます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="179" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[179]</anchor-end> 第2引数の <var>h</var> はここまでに処理した<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数です。 <var>h</var> に1を足しているのは、ループの今周で処理していた <var>delta</var> の分です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="180" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[180]</anchor-end> <var>b</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の数 (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="177" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;177</anchor-internal>) です。これと <var>h</var> を比較しているので、最初の <var>delta</var> であったかどうかが第3引数の値となります。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="117" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[117]</anchor-end> <pre class="code">         let delta = 0</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="181" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[181]</anchor-end> 次の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>は今回処理し終えた非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>からの差分によって表現しますので、ここで一端 <var>delta</var> は 0 に戻します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="118" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[118]</anchor-end> <pre class="code">         increment h</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="184" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[184]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>1つ分の処理を終えたので、処理済み<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数である <var>h</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>します。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="185" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[185]</anchor-end> これは <var>input</var> の長さより短く、 <var>input</var> の長さは表現できるという仮定があるので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>することはありません (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="91" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;91</anchor-internal> と同じ)。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="182" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[182]</anchor-end> <pre class="code">       end</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="192" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[192]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="80" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;80</anchor-internal> からの <var>c</var> の値の条件分岐がここで終わります。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="183" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[183]</anchor-end> <pre class="code">     end</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="186" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[186]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="120" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;120</anchor-internal> からの内側のループはここで終わります。 <var>input</var> にまだ続きがあれば、更にもう一周します。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="188" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[188]</anchor-end> 現在の <var>n</var> と同じ値の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>が <var>input</var> の続きにまだあるかもしれませんし、ないかもしれません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="189" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[189]</anchor-end> <var>input</var> にもう続きがないとしたら、値が <var>n</var> <weak xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(<anchor>以下</anchor>)</weak> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>はもう残っていないので、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="119" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;119</anchor-internal> に進みます。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="119" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[119]</anchor-end> <pre class="code">     increment delta and n</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="193" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[193]</anchor-end> 前の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>からの差が一つ開いたという意味で、 <var>delta</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>します (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="122" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;122</anchor-internal>)。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="194" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[194]</anchor-end> 次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を処理するという意味で (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="189" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;189</anchor-internal>)、 <var>n</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="91" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[91]</anchor-end> この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>の直前において <var>delta</var> は <var>input</var> の長さより小さく、 <var>input</var> の長さは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>せずに表せることを前提としているので、 <var>delta</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>しても<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>しません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="92" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[92]</anchor-end> <var>n</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>するおそれがあります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="93" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[93]</anchor-end> <var>n</var> は <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="88" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;88</anchor-internal> で <var>m</var> を代入しています。これは <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;94</anchor-internal> で代入された<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>となります。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>はすべて<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>として表せると仮定しているので <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.</src>、
ここまで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>せずに処理できています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="97" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[97]</anchor-end> さて、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>の最大値の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>が <var>n</var> に入っていると、
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">インクリメント</anchor>で<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="95" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[95]</anchor-end> しかし、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="94" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;94</anchor-internal> 
で最小の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>から順に処理しているということは、最大値である<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>は最後になってはじめて
<var>m</var>、ひいては <var>n</var> に代入されます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="96" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[96]</anchor-end> その場合、 <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="75" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;75</anchor-internal> の条件より 
<weak xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(<var xmlns="http://www.w3.org/1999/xhtml">h</var>、つまり処理済みの<anchor>符号位置</anchor>の数が <var xmlns="http://www.w3.org/1999/xhtml">input</var> の長さと一致する、つまり最後の<anchor>符号位置</anchor>まで処理し終えて条件を満たさなくなったため)</weak>
どのみちループを抜けます。
ループを抜けて終わるだけなので、 <var>n</var> が桁溢れしても問題ありません <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="2" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;2</anchor-internal> 6.3</src>。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="90" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[90]</anchor-end> <pre class="code">   end</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="187" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[187]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="75" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;75</anchor-internal> からの外側のループはここで終わります。 <var>h</var> がまだ <var>input</var> の長さに達していなければ、更にもう一周します。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="190" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[190]</anchor-end> <var>h</var> がまだ <var>input</var> の長さに達していないということは、 <var>n</var> より大きな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>がまだあるので、その処理に移ります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="191" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[191]</anchor-end> <var>h</var> が <var>input</var> の長さに等しいなら、これ以上大きな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>は残っていないので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>は完了です。</li></ul></li></ul></section><section><h1>復号</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="222" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[222]</anchor-end> 次に示すのは、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2 に示された <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">擬似コード</anchor>に注釈を加えたものです。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="223" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[223]</anchor-end> <pre class="code">   let n = initial_n</pre></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="270" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[270]</anchor-end> <pre class="code">   let i = 0</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="272" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[272]</anchor-end> <var>i</var> は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>した値を入れていく変数です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="273" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[273]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>として<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>されている各値は一つ前の値からの差分なので (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="18" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;18</anchor-internal>)、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>は一つ前の値に足し合わせていく (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="267" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;267</anchor-internal>) ことで行います。最初の値はその一つ前がないので、 0 からはじめます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="271" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[271]</anchor-end> <pre class="code">   let bias = initial_bias
   let output = an empty string indexed from 0</pre></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="248" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[248]</anchor-end> <pre class="code">   consume all code points before the last delimiter (if there is one)
     and copy them to output, fail on any non-basic code point</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="243" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[243]</anchor-end> 入力に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>が含まれていれば、その前までは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置分居</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="17" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;17</anchor-internal>)
によって最初に集められた<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>の列なので、それを<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">出力</anchor>に複写します。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="244" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[244]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>が含まれていなければ、全体が <var>delta</var> を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>したものなので、ここでは何も複写しません。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="245" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[245]</anchor-end> 複写する部分はすべて<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>のはずですが、非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が含まれているとすればそれは正しい
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> ではないので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">失敗</anchor>とします。</li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="242" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[242]</anchor-end> <pre class="code">   if more than zero code points were consumed then consume one more
     (which will be the last delimiter)</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="247" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[247]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="248" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;248</anchor-internal> で1つ<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以上</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を複写したなら、もう1<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>分先に進みます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="249" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[249]</anchor-end> この1<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>分というのは、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>とその後の <var>delta</var> の部分の間にある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">区切子</anchor>となります。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="246" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[246]</anchor-end> <pre class="code">   while the input is not exhausted do begin</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="251" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[251]</anchor-end> <var xml:lang="en">input</var> が終わるまで繰り返します。あるいは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>全体が異常終了することがあります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="253" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[253]</anchor-end> この外側のループは <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="252" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;252</anchor-internal> まで (つまり<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>の最後まで) 続きます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="250" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[250]</anchor-end> <pre class="code">     let oldi = i</pre></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="256" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[256]</anchor-end> <pre class="code">     let w = 1</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="258" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[258]</anchor-end> <var>w</var> は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="22" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;22</anchor-internal>) における各<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">重み</anchor>を表しています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="259" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[259]</anchor-end> まずは一番下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>なので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">重み</anchor>の初期値は 1 です。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="257" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[257]</anchor-end> <pre class="code">     for k = base to infinity in steps of base do begin</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="261" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[261]</anchor-end> ここからの内側のループでは、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>を一桁ずつ読んで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>していきます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="262" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[262]</anchor-end> このループは <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="263" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;263</anchor-internal> まで続きます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="265" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[265]</anchor-end> <var>k</var> は <var>base</var> にループの回数 (最初は 1) を掛けた値となります。各<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">重み</anchor>の基準値的なもので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>における <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="151" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;151</anchor-internal> と対応しています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="266" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[266]</anchor-end> このループは <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="229" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;229</anchor-internal> の条件が成立した時だけ正常に抜けます。あるいは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>全体が異常終了することがあります。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="260" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[260]</anchor-end> <pre class="code">       consume a code point, or fail if there was none to consume
       let digit = the code point's digit-value, fail if it has none</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="268" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[268]</anchor-end> 1<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor> (一<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>分) <var>input</var> から読み込みます。正常な入力なら、必ず存在する上、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>としての値が定義されているはずです。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="269" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[269]</anchor-end> 異常な入力なら存在しない (<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>の途中で切れている) 場合や<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>としての値が定義されていない<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>である場合があり、それらの場合にはここで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>全体が終了します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="267" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[267]</anchor-end> <pre class="code">       let i = i + digit * w, fail on overflow</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="274" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[274]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="270" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;270</anchor-internal> の通り <var>i</var> は次の値を表すことになり、それは前の値からの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">差分</anchor>として<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>されているので、元の <var>i</var> に足していきます。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="275" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[275]</anchor-end> 内側のループの現在の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>が表す値である <var>digit</var> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="260" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;260</anchor-internal>) に現在の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">重み</anchor>である <var>w</var> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="256" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;256</anchor-internal>) を掛けることで、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>のこの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>が表す値が求まり、それを <var>i</var> に足します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="276" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[276]</anchor-end> その結果<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>するなら、正しく処理できない入力であるため、ここで<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>全体を終了します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="228" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[228]</anchor-end> <pre class="code">       let t = tmin if k &lt;= bias {+ tmin}, or
               tmax if k &gt;= bias + tmax, or k - bias otherwise</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="277" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[277]</anchor-end> <var>t</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>においてこの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>があるかどうかを決める<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="24" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;24</anchor-internal>) です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="278" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[278]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>における <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="153" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;153</anchor-internal> に対応します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="230" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[230]</anchor-end> <var>t<sub>min</sub></var> を足す部分は、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>の時 (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="84" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;84</anchor-internal>) と同様に省略できます。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="229" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[229]</anchor-end> <pre class="code">       if digit &lt; t then break</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="280" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[280]</anchor-end> この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の値である <var>digit</var> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> <var>t</var> より小さければ、この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>で現在の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>は終わりです。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="281" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[281]</anchor-end> よって内側のループを抜けて <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="264" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;264</anchor-internal> に進みます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="279" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[279]</anchor-end> <pre class="code">       let w = w * (base - t), fail on overflow</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="282" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[282]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">重み</anchor> <var>w</var> を次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>用に更新します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="283" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[283]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の個数である <var>base</var> から、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">閾値</anchor> <var>t</var>、つまり続きの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>がない<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の数を除いたものが、続きがある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の個数です。従ってそれをかけたものが次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>での<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">重み</anchor>となります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="284" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[284]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>するなら、正しく処理できないので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>全体を終えます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="263" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[263]</anchor-end> <pre class="code">     end</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="285" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[285]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="257" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;257</anchor-internal> からの内側のループはここで終わります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="286" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[286]</anchor-end> ここでループを抜けて次に進むことはなく、必ずもう一度実行されます。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="264" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[264]</anchor-end> <pre class="code">     let bias = adapt(i - oldi, length(output) + 1, test oldi is 0?)</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="288" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[288]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="250" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;250</anchor-internal> で保存した前の <var>i</var> と現在の <var>i</var> の差が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>として<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>されていた値であり、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>でいう <var>delta</var> です。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="289" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[289]</anchor-end> これを使って<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">偏差適応</anchor> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="56" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;56</anchor-internal>) により次の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>のための <var>bias</var> を決定します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="290" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[290]</anchor-end> 第2引数はここまでに処理を終えた<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の数であり、このループで処理している値はまだ <var>output</var> に入っていないので、 1 足しています。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="291" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[291]</anchor-end> 第3引数は一つ目の非<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>であったなら<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">真</anchor>となります。なぜなら
<var>i</var> は後から 0 になることはなく (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="267" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;267</anchor-internal>, <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="292" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;292</anchor-internal>, <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="299" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;299</anchor-internal>)、 
<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="270" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;270</anchor-internal> で初期化した後最初にここに到達した時だけ 0  となるからです。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="287" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[287]</anchor-end> <pre class="code">     let n = n + i div (length(output) + 1), fail on overflow</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="293" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[293]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を表す <var>n</var> (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="223" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;223</anchor-internal>) を更新します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="294" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[294]</anchor-end> 前の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>からの差が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>として<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>されていたので、元の <var>n</var> に足します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="295" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[295]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>の差は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>の時に上位の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>に入れられているので (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="78" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;78</anchor-internal>)、
一番下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>を落としたものを足します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="292" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[292]</anchor-end> <pre class="code">     let i = i mod (length(output) + 1)</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="296" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[296]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="287" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;287</anchor-internal> で求めた<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>を挿入する位置を決めるため、 <var>i</var> の一番下の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁</anchor>だけを取り出します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="224" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[224]</anchor-end> <pre class="code">     {if n is a basic code point then fail}</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="297" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[297]</anchor-end> ところで、 <var>n</var> は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>を表すこともあり得ますが、 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor>
としては認めていないので、そうであったなら不正な入力であるとして<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>全体を<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">停止</anchor>します。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="226" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[226]</anchor-end> すべての<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>が <var>n<sub>initial</sub></var> よりも小さければ、
<var>n</var> は常に <var>n<sub>initial</sub></var> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">以上</anchor>となるため、この条件が成立することはなく、
省略できます。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="298" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[298]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="223" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;223</anchor-internal> のように <var>n</var> の初期値を決めた上で <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="287" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;287</anchor-internal> のように<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">単調増加</anchor>にだけ変化するからです。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="227" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[227]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> はこの条件に当てはまります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src></li></ul></li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="225" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[225]</anchor-end> <pre class="code">     insert n into output at position i</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="300" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[300]</anchor-end> <var>output</var> の位置 <var>i</var> に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor> <var>n</var> を挿入します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="299" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[299]</anchor-end> <pre class="code">     increment i</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="301" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[301]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="225" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;225</anchor-internal> で1<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>挿入しましたが、最も近い次の挿入可能な位置はその次であるので、 <var>i</var>
に1足します。</li></ul><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="252" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[252]</anchor-end> <pre class="code">   end</pre></p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="254" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[254]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="246" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;246</anchor-internal> からの外側のループがここで終わります。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="255" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[255]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>全体もここで終わり、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">停止</anchor>します。</li></ul><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="231" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[231]</anchor-end> とある<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>の列が与えられた時、それを表現できる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>された文字列は、ただ一つだけ存在します。  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="232" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[232]</anchor-end> というのは、この<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>器の状態は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">単調増加</anchor>するだけであり、  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="233" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[233]</anchor-end> かつ<var>delta</var> の表現方法は一種類だけであるためです。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="234" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[234]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">誤り条件</anchor>として起こり得るのは、  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="235" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[235]</anchor-end> 不正な<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="236" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[236]</anchor-end> 予期せぬ <var>input</var> の終了</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="237" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[237]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="238" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[238]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">基本符号位置</anchor>がそのままではなく<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>されて出現する</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="239" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[239]</anchor-end> ... といったものがあります。  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="240" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[240]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>器がこれらの誤りで失敗した場合には、他のどんな <var>input</var> とも同じ出力を生成することはありません。  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="241" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[241]</anchor-end> そのため、出力を再<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>してもとの <var>input</var> と照らし合わせなくても、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">固有性</anchor>を保証できます。  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.2</src></li></ul></li></ul></li></ul></section><section><h1>桁溢れの処理</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="304" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[304]</anchor-end> 符号化と復号の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">算法</anchor>中に現れている通り、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>の処理が必要となります。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> を <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">IDNA</anchor> で使う場合は26ビットの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号無し整数</anchor>があれば十分です
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src>。 <weak xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">(<anchor>Punycode</anchor> の項を参照。)</weak> 
それ以外の場合はより大きな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>が必要になることもあるでしょう。</p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="305" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[305]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>の処理方法は何通りか考えられ、どれが簡便であるかは<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>にも依存します。</p><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="306" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[306]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>を検出できない<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">プログラミング言語</anchor>では、次の計算により<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>を検出できます
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src>。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="307" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[307]</anchor-end> <var>A</var>, <var>B</var> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">非負整数</anchor>、<var>C</var> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">正整数</anchor>、<var>maxint</var>
が表現できる<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">最大</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>であるとき、</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="308" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[308]</anchor-end> <code class="math"><var>A</var> + <var>B</var></code> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>することの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">必要十分条件</anchor>は、
<code class="math"><var>B</var> &gt; <var>maxint</var> - <var>A</var></code> であること。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="309" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[309]</anchor-end> <code class="math"><var>A</var> + (<var>B</var> × <var>C</var>)</code> が<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>することの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">必要十分条件</anchor>は、
<code class="math"><var>B</var> &gt; (<var>maxint</var> - <var>A</var>) <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">div</anchor> <var>C</var></code> であること。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="310" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[310]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>が発生し得る<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">入力</anchor>を事前に検出する方策も採れます <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src>。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="311" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[311]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>において、次の条件が成り立てば、 <var>delta</var> は <code class="math">(<var>M</var> - <var>initial<sub><var>n</var></sub></var>) × (<var>L</var> + 1)</code> を超えることはありません。  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="312" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[312]</anchor-end> <var>input</var> に<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号位置</anchor>で <var>M</var> を超えるものがないこと。</li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="313" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[313]</anchor-end> <var>input</var> の長さが <var>L</var> を超えないこと。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="314" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[314]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>を途中で検出する方法よりは入力に対する制限が厳しくなります  <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src>。<ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="315" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[315]</anchor-end> が、 <var>M</var> と <var>L</var> が十分大きければ実用上問題なくなります。</li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="316" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[316]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>でも同じようなことができます。<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一般化可変長整数</anchor>の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の列の長さを制限することとなります。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="317" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[317]</anchor-end> つまり内側のループ (<anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="257" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;257</anchor-internal>) の繰り返し数を制限することとなります。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="318" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[318]</anchor-end> ただしこの<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">数字</anchor>の列は長くなることがあるので、32ビットよりも大きな<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">整数</anchor>が必要になるでしょう。
<src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src></li></ul></li></ul></li><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="319" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[319]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号</anchor>した後再度<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">符号化</anchor>し、それが元の<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">文字列</anchor>と<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">一致</anchor>するかの比較により<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>を検出することもできます。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="320" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[320]</anchor-end> この方法なら<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>を途中で検出する方法より入力に対する制限が厳しくなることはありません。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src><ul><li><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="321" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[321]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">IDNA</anchor> の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ToUnicode</anchor> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">演算</anchor>ではこれをしているので、<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">ToUnicode</anchor>
でしか<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">復号器</anchor>を使わないなら、実は<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">桁溢れ</anchor>の検出は不要です。 <src xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> 6.4</src></li></ul></li></ul></li></ul></section><section><h1>実装</h1><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="329" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[329]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">RFC 3492</anchor> には <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">C言語</anchor>による実装例があります。
<anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> 用ではありますが、容易に他の <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Bootstring</anchor> にも拡張できます。
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://tools.ietf.org/html/rfc3492#appendix-B">http://tools.ietf.org/html/rfc3492#appendix-B</anchor-external></p><comment-p xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:10:"><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="330" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[330]</anchor-end> <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">大文字・小文字混合注釈</anchor>には対応していません。</comment-p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="12" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[12]</anchor-end> <cite>Encode::Bootstring - search.cpan.org</cite>
<anchor-external xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resScheme="URI" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:resParameter="http://search.cpan.org/dist/Encode-Bootstring/lib/Encode/Bootstring.pm">http://search.cpan.org/dist/Encode-Bootstring/lib/Encode/Bootstring.pm</anchor-external></p><p><anchor-end xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="331" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">[331]</anchor-end> <anchor-internal xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:" a0:anchor="12" xmlns:a0="urn:x-suika-fam-cx:markup:suikawiki:0:9:">&gt;&gt;12</anchor-internal> はちょっと物足りない感じでした。 <anchor xmlns="urn:x-suika-fam-cx:markup:suikawiki:0:9:">Punycode</anchor> を実装できない。</p></section></body></html>