正規S式(またはcsexp )は、一般S式(またはsexp)のサブセットをバイナリ形式で符号化したものです。これは、 SPKIで使用するために設計され、S式の強力な機能を維持しつつ、デジタル署名などのアプリケーションで正規形式を保証すると同時に、バイナリ形式のコンパクトさを実現し、解析速度を最大化します。
ここで適用可能な一般的なS式の特定のサブセットは、バイト列であるアトムと、リストまたはサブリストを区切るために使用される括弧で構成されています。これらのS式は完全に再帰的です。
S式は通常、テキストとしてエンコードされ、スペースで原子が区切られ、スペースを含む原子は引用符で囲まれますが、標準エンコードを使用する場合は、各原子は長さが接頭辞として付加されたバイト列としてエンコードされます。リスト内の隣接する要素を区切る空白は許可されません。原子の長さは、ASCIIの10進数値の後に「:」を付けて表されます。
セックス
(この「標準S式」は5つの原子から構成されています)
csexpになります
(4:this22:Canonical S-expression3:has1:55:atoms)
長さ接頭辞がアトムの末尾を明確に示しているため、「Canonical S-expression」アトム内部の空白文字をエスケープするために引用符は必要ありません。リスト内のアトムと次の要素の間には空白文字は存在しません。
csexpは一般的に空のリストや空のアトムなどを許容しますが、 csexpの特定の用途では追加の制約が課されます。たとえば、SPKIで使用されるcsexpは、一般的なcsexpと比較して1つの制限があります。それは、すべてのリストがアトムで始まる必要があり、したがって空のリストは存在できないということです。
通常、リストの最初の要素は、XMLの要素名と同様に扱われます。
他にも一般的に使用されているエンコーディング方式があります。
一般的に、csexpのパーサーはXMLやASN.1のパーサーよりも1桁か2桁小さい。 この小さなサイズとそれに伴う処理速度がcsexpの最大の利点である。パース性能の優位性以外にも、いくつかの違いがある。
csexpとXMLの違いは、 csexpがデータ表現フォーマットであるのに対し、XMLはデータ表現フォーマットとスキーマ機構の両方を備えている点です。そのため、XMLは特定の種類のデータ(例えば、 HTML、 ATOM、 SVG、 MathML、あるいは必要に応じて新しい文法)に合わせて「構成」することができます。XMLには文書文法を定義するための言語があり、 DTDはXML標準自体で定義されていますが、 XSD、 RelaxNG、 Schematronは追加機能のためにXMLと併用されることが多く、またXMLはスキーマなしでも動作します。csexpデータはもちろん上位レベルで実装されたスキーマによって操作できますが、 csexp自体にはそのような機構は提供されていません。
文字とバイトに関して言えば、csexp の「文字列」は、各アトムに長さプレフィックスが付いているため、任意のバイトシーケンスを持つことができます。一方、XML(通常の Lisp S 式、JSON、プログラミング言語のリテラルなど)では、一部の文字(「<」やほとんどの制御文字など)に対して別の表現方法が必要です。ただし、これは表現できる構造や意味の範囲には影響しません。また、XML は、特定のバイトシーケンスをどのように解釈するかを指定するメカニズムも提供します。たとえば、Unicode UTF-8文字列、JPEGファイル、または整数として解釈するかなどです。csexpでは、このような区別は外部のメカニズムに任されています。
最も基本的なレベルでは、csexpと XML はどちらもツリー構造を表します (他のほとんどの外部表現と同様)。これは、XML は LISP のような S 式の句読点が異なる形式として説明でき、またその逆も可能であるため、驚くべきことではありません。[ 1 ]
しかし、XMLには追加のセマンティクスが含まれており、これはcsexpでは言語の一部としてではなく、さまざまな慣習によって実現されるのが一般的です。まず、すべてのXML要素には名前があります(csexpアプリケーションでは、通常、各式の最初の子要素がこれに使用されます)。次に、XMLは、まずスキーマ文法を介してデータ型を提供します。ただし、スキーマは、整数、文字列、型を持つデータオブジェクト(例:JPEG)、および(特にXSDでは)その他の型を区別することもできます。
XML要素には属性を持たせることもできますが、これはcsexpにはない構造です。csexpでXMLデータを表現するには、このような属性の表現方法を選択する必要があります。分かりやすい例としては、各S式の2番目の項目を(名前と値の)ペアのリスト用に予約する方法があります。これはLISPの連想リストに相当します。XMLのID属性とIDREF属性はcsexpには同等のものはありませんが、 csexpアプリケーションプログラムで簡単に実装できます。
最後に、XML要素にはコメントや処理命令が含まれる場合があります。csexpにはこれに相当する特定の機能はありませんが、それぞれに名前を予約するだけで簡単に表現できます。例えば、「*COM」や「*PI」といった名前を付けます(「*」はXML要素の型名との衝突を防ぎます)。
(4:*COM15:コメント本文) (3:*PI6:target11:font="helv")
csexpとXMLはどちらも完全に再帰的です。
csexpリストの最初の原子は、慣例として、リストの「タイプ」を識別する際に、おおよそ XML 要素タイプ名に対応します。ただし、csexpでは、これは任意のエンコーディングの任意の原子 (JPEG、Unicode 文字列、WAVファイルなど) にすることができますが、XML 要素名は、プログラミング言語の識別子のように、特定の文字に制限された識別子です。csexpの方法は明らかに汎用的です。一方、そのようなアイテムがどのエンコーディングであるかを識別し、それをどのように解釈するかは、特定のユーザーの慣例によってのみ決定されます。つまり、csexpアプリケーションは、コード、ドキュメントなどで、そのような慣例を独自に構築する必要があります。
同様に、csexpアトムはバイナリ(長さの接頭辞の後に任意のバイト列が続く)であるのに対し、XML は人間が読みやすいように設計されています(JSONやYAMLほどではないかもしれませんが)。そのため、XML 内の任意のバイト列は何らかの方法でエンコードする必要があります(たとえば、ビットマップ画像はbase64を使用して含めることができます)。つまり、大量の読み取り不可能な情報を非圧縮 XML に格納するにはより多くのスペースが必要になります。一方で、異なる文字セット間での変換(異なる文字セット、改行規則などを適用する可能性のあるネットワーク ホストを介した送信を含む)にも耐えることができます。
XMLは1つの要素内の文字列のシーケンスを1つの文字列に「マージ」するのに対し、csexpはリスト内の原子のシーケンスを許可し、それらの原子は互いに分離されたままであると示唆されてきましたが、これは誤りです。[ 2 ] S式やcsexpとまったく同じように、XMLは「文字列」が何らかの方法で分離されている場合にのみ「文字列のシーケンス」の概念を持ちます。
<s>文字列A </s><s>文字列B </s>対 <s>文字列 A 文字列B </s>(「文字列A」「文字列B」) 対 ("文字列A" 文字列B")(8:文字列A 8:文字列B) 対 (16:文字列A、文字列B)
ASN.1は広く使われているバイナリエンコーディング形式です。しかし、構文(データ型)のみを表現し、意味論は表現しません。2つの異なる構造(それぞれ2つの整数からなるシーケンス)は、特別なタグによる区別がない限り、ネットワーク上では同一の表現になります。ASN.1構造を解析するには、パーサーに期待する構造のセットを伝える必要があり、パーサーは解析対象のデータ型を構造オプションと照合しなければなりません。これがASN.1パーサーの複雑さを増す要因となっています。
csexp構造は、そのセマンティクスを示す何らかの情報(要素名にエンコードされている)を含んでおり、csexp構造のパーサーは、解析対象の構造が何であるかを気にしません。ワイヤフォーマット式が内部ツリー形式(XMLのDOMに類似)に解析されると、その構造の利用者は、期待どおりの形式になっているかどうかを調べることができます。スキーマを持たないXMLドキュメントは、この点ではcsexpと全く同じように動作しますが、スキーマを持つXMLドキュメントは、ASN.1に近い動作をします。