ASN.1はデータ型を記述する記述言語であり、基本的なデータ型を元に新しいデータ型を定義できます。 例えば、電話番号を表す新たなデータ型(TelephoneNumber)を、 すでに定義してある数字列型(NumericString)で定義する場合、以下の様に記述します。
TelephoneNumber ::= NumericString
ASN.1では基本的なデータ型を組み合わせたり、制限をつけたりして新たなデータ型を定義できます。 例えば、電話番号を3〜11桁の数字列型(NumericString)で定義する場合、以下の様に記述します。
TelephoneNumber ::= NumericString (SIZE(3..11))
数値や文字列の様な構造上分解できないデータ型を単純型(あるいは基本型)といいます。 主な単純型のデータ型としては、以下のものがあります。
単純型 | 説明 |
論理型 (BOOLEAN) |
TRUEかFALSEの論理値を持つデータ型です。 |
ヌル型 (NULL) |
形式的な穴埋めデータ型で、選択型(CHOICE)で選択肢がない場合や、 順序列型(SEQUENCE)の要素で存在だけが意味があり値に意味がない様な場合に使用します。 |
整数型 (INTEGER) |
整数値データに使用します。 |
実数型 (REAL) |
実数値データに使用します。 |
列挙型 (ENUMERATED) |
値を並べて定義する型です。
定義する場合は、括弧で括って値を列挙します。
列挙値に対し整数値を指定することも可能です。
例:Day ::= ENUMERATED { monday(0), tuesday, wednesday, thursday, friday, saturday, sunday } |
ビット列型 (BIT STRING) |
ビット値の並びの型です。 |
オクテット列型 (OCTET STRING) |
8ビットの値(オクテット)の並びの型で、バイナリデータなどに使用します。 |
オブジェクト識別子型 (OBJECT IDENTIFIER) |
オブジェクト識別型は、オブジェクトを表すためのデータ型であり、 オブジェクトを一意に特定するために使用します。 ASN.1ではオブジェクトを一意に識別するためのツリーを作っており、 オブジェクト識別子は、ツリー構造上のルートから目的のオブジェクトまでのノードの列(数字列)として規定されます。 実際に使用する場合は、登録が必要です。 |
(制限)文字列型 (...String) |
文字列に使用します。 NumericString -- 空白と数字 PrintableString -- 空白と英数字と次の記号"'()+,-./:=?" VisibleString ISO646String IA5String TeletexString T61String VideotexString GraphicString GeneralString UniversalString -- ユニコード文字列 BMPString -- UCS2のユニコード文字列 UTF8String -- UTF−8のユニコード文字列 などあります。 文字列型は元々オクテット列型(OCTET STRING)から派生した型として定義されていたため、 全て大文字ではなく、頭だけ大文字で記述します。 |
一方1つ上のデータ型が何層にも組合わさった複雑な形のデータ型を構造型といいます。 例えば氏名、電話番号、fax番号の情報を持つ電話帳のデータ型を定義する場合、以下の様に記述します。
TelephoneNumberRecord ::= SET { name VisibleString, tel TelephoneNumber, fax TelephoneNumber }
主な構造型のデータ型としては、以下のものがあります。
選択型 (CHOICE) |
複数の型の中から、1つの型を使用します。
Credit-card ::= SEQUENCE { number NumericString (SIZE (20)), expiry-date NumericString (SIZE (6)) -- MMYYYY -- } |
順序列型 (SEQUENCE) |
複数の型の並びです。順序に意味があります。Point ::= SEQUENCE { x INTEGER, y INTEGER } |
単一順序列型 (SEQUENCE OF) |
0個以上の単一の型の並びです。順序に意味があります。Line ::= SEQUENCE OF Point |
集合型 (SET) |
複数の型の集合です。順序に意味がありません。Human ::= SET { name PrintableString, age INTEGER} |
単一集合型 (SET-OF) |
0個以上の単一の型の並びです。順序に意味があります。PrimeNumber ::= SET OF INTEGER |
ANY | 任意のASN.1型を設定できる入れ物として使われます。 無条件にANYを使用すると符号化できなくなるため、使用は望ましくありません。 |
外部型 (EXTERNAL) |
フォーマットが、他で定義される型です。
何でも設定できる入れ物として使われます。外部型(EXTERNAL)は以下の様に、定義されています。EXTERNAL ::= [UNIVERSAL 8] IMPLICIT SEQUENCE { direct-reference OBJECT IDENTIFIER OPTIONAL, indirect-reference INTEGER OPTIONAL, data-value-descriptor ObjectDescriptor OPTIONAL, encoding CHOICE { single-ASN1-type [0] ANY, octet-aligned [1] IMPLICIT OCTET STRING, arbitrary [2] IMPLICIT BIT STRING }} |
集合型(SET)などの構造型のデータ型ではOPTIONAL指定をすることで省略可能なデータを指定することができます。
型には、曖昧になる事を避けるために、タグを付ける事が出来ます。 特に、選択型(CHOICE)の選択肢に同じ型がある場合(例えば、整数型の「年齢」と整数型の「学年」が選択できる場合)や 順序列型(SEQUENCE)や集合型(SET)において省略可能な要素がある場合に、 省略することでデータが曖昧になることを避けるために各要素にタグをつけることができます。 タグは鍵括弧で括って記述します。 例えば住所や電話番号の省略ができるデータ型を定義する場合、以下の様に記述します。
TelephoneNumberRecord ::= SET { name VisibleString, country [1] VisibleString OPTIONAL, states [2] VisibleString OPTIONAL, tel [2] TelephoneNumber OPTIONAL, fax [3] TelephoneNumber OPTIONAL }
ASN.1では4区分のタグが存在しています。
[UNIVERSAL 数]
[APPLICATION 数]
[数]
[PRIVATE 数]
汎用クラスでのタグ番号は以下の通りです。なお、選択型に対するタグ番号はありません。
タグ番号 | 型 |
[UNIVERSAL 0] | BER符号化で、可変長形式で、終わりを示すための使用する |
[UNIVERSAL 1] | 論理型(BOOLEAN) |
[UNIVERSAL 2] | 整数型(INTEGER) |
[UNIVERSAL 3] | ビット列型(BIT STRING) |
[UNIVERSAL 4] | オクテット列型(OCTET STRING) |
[UNIVERSAL 5] | ヌル型(NULL) |
[UNIVERSAL 6] | オブジェクト識別子型(OBJECT IDENTIFIER) |
[UNIVERSAL 7] | ObjectDescriptor |
[UNIVERSAL 8] | 外部型(EXTERNAL), INSTANCE OF |
[UNIVERSAL 9] | 実数型(REAL) |
[UNIVERSAL 10] | 列挙型(ENUMERATED) |
[UNIVERSAL 11] | EMBEDDED PDV |
[UNIVERSAL 12] | UTF8String |
[UNIVERSAL 13] | RELATIVE-OID |
[UNIVERSAL 16] | 順序列型(SEQUENCE), 単一順序列型(SEQUENCE OF) |
[UNIVERSAL 17] | 集合型(SET), 単一集合型(SET-OF) |
[UNIVERSAL 18] | NumericString |
[UNIVERSAL 19] | PrintableString |
[UNIVERSAL 20] | TeletexString, T61String |
[UNIVERSAL 21] | VideotexString |
[UNIVERSAL 22] | IA5String |
[UNIVERSAL 23] | UTCTime |
[UNIVERSAL 24] | GeneralizedTime |
[UNIVERSAL 25] | GraphicString |
[UNIVERSAL 26] | VisibleString, ISO646String |
[UNIVERSAL 27] | GeneralString |
[UNIVERSAL 28] | UniversalString |
[UNIVERSAL 29] | CHARACTER STRING |
[UNIVERSAL 30] | BMPString |
部分型あるいは制約と呼ばれるものは、親の型から特定の制約を付けて部分型を作ったものです。 部分型の定義は以下の様に、親の型の後に括弧で制限条件を書きます。
部分型 ::= 親型 ( 制限 )
但し、SET OF やSEQUENCE OFでは、OFの後に来る型との制限の混同を避けるために、 SETやSEQUENCE自身の制限はOFの前に書きます。 例えば、長さ1〜10文字の文字列が、1〜50個含まれる集合は、以下の様になります。
MemberList ::= SET SIZE(1..50) OF String(SIZE(1..10))
前のSIZEはSETの要素数を制限し、後のSIZEはStringの文字数を制限します。 制限には、部分型制限と一般制限があります。 一般制限はASN.1 仕様で記述しきれない実装上の制約を記載する事もできますが、 説明は省略します (というか理解しきれない)。 部分型制限は、基本的な制限要素と、制限要素の組合せ(演算)によって記載します。
PrimeNumbers ::= INTEGER ( 2 | 3 | 5 | 7 | 11 | 13 ) PushButtonDial ::= IA5String ("0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"|"*"|"#") -- PushButtonDialは1文字の文字列です。
Example1 ::= INTEGER((1..10) ^ (5..15))
Example1 ::= INTEGER(1..10)(5..15)
Interval ::= INTEGER (0..12)
name ::= PrintableString (SIZE (1..20)), Matrix ::= SEQUENCE SIZE (6) OF SEQUENCE SIZE (6) OF INTEGER(-100..100) -- Matrixは6×6行列で、各値は-100〜100の整数である行列
CapitalLettersAndSpaces ::= PrintableString (FROM ("A".."Z"|" "))
TextBlock ::= SEQUENCE OF VisibleString Address ::= TextBlock (SIZE (3..6))(WITH COMPONENT (SIZE (1..32)))
上記の制約は、基本となる制限の規定の後に、拡張マーク("...")を付ける事で、将来拡張可能なります。 拡張が規定された場合は、拡張マークの後に、拡張された制限を記載します。 複数の拡張がある場合、拡張マーク("...")を複数付ける事で複数回の拡張を明示することもできるようです (ASN.1の版数によって多少異なる模様)。
例: A ::= INTEGER (0..10, ...) 例: A ::= INTEGER (0..10, ..., 12) 例: RadioButton ::= ENUMERATED { button1, button2, button3, ... } 例: RadioButton ::= ENUMERATED { button1, button2, button3, ..., button4, button5 }
SEQUENCEやSETやCHOICEにおいて、複数回数の拡張が行われた場合、 ASN.1仕様から明確に拡張回数を読み取れるようにす るために、 1回の拡張で追加した要素をまとめて2重の鍵括弧で囲みます (追加要素が1つの場合は、囲んでも囲まなくてもよい)。 ASN.1のデコーダはASN.1仕様書の2重鍵括弧を識別して、 どのバージョンのメッセージが使われているかを識別し、 必須要素が欠けている場合にエラーを出すことが可能です。
例:Dimensions ::= SET { x INTEGER, y INTEGER, ..., z INTEGER } -- version 2 例:Afters ::= CHOICE { cheese IA5String, dessert IA5String, ..., [[ coffee NULL ]] } -- version 2 例:Afters ::= CHOICE { cheese IA5String, dessert IA5String, ..., [[ coffee NULL, tea NULL ]] , -- version 2 [[ cognac IA5String ]] } -- version 3 例:Type ::= SEQUENCE { component1 INTEGER, component2 BOOLEAN, -- version 1 ... } 例:Type ::= SEQUENCE { component1 INTEGER,
component2 BOOLEAN, ..., [[ component3 REAL ]], -- version 2 ... }
ASN.1モジュールで EXTENSIBILITY IMPLIEDが指定されている場合、 選択型(CHOICE)と列挙型(ENUMERATED)と順序列型(SEQUENCE)と集合型(SET)は 拡張マークを含んでいると解釈します。