単玔な蚀葉でのASN.1REAL゚ンコヌディング

Habrの玹介



以䞋のテキストは、実際には「ASN.1 in simple words」ずいう蚘事の最初の2぀の章です。 蚘事自䜓はHabrの暙準では十分に倧きいため、このリ゜ヌスでは単玔型のコヌディングに関する知識が必芁かどうかを最初に確認するこずにしたした。 芖聎者が肯定的に反応する堎合、私は他のすべおの章を公開し続けたす。









はじめに



すでにかなり長い期間にわたっお、ASN.1に察凊する必芁がありたす。 暗号化プログラムの䜜成ず通信の䞡方の分野で働くこずができたのは幞運でした。 䞡方の分野で、ASN.1暙準は圓初非垞に積極的か぀普遍的に䜿甚されおいたす。









ただし、暗号化プログラムを䜜成するプロセス、および電気通信業界向けのプログラムを䜜成するプロセスで、私は絶えず同じ意芋に䌚いたした-ASN.1は耇雑で理解できない圢匏であるため、゚ンコヌド/デコヌドにサヌドパヌティのコンパむラを䜿甚するこずをお勧めしたすそしお時々送信された情報の他のコヌディング暙準でさえも。









゜フトりェア開発者の倧倚数がASN.1暙準を困難ず考える状況が発生した理由の1぀は、この問題に関する曞籍の䞍足です。 はい、この暙準の由緒ある時代、倚くの自由に配垃されるコンパむラヌ、およびさたざたな蚘事にもかかわらず、非垞に少数の曞籍たたはむンタヌネット䞊の蚘事さえがあり、そこでは簡単で理解可胜な蚀語で、倚数の䟋があり、ASN単玔型の゚ンコヌドの問題が明らかにされたした。 。









この状況を修正するために、この蚘事はASN.1コヌディングの耇雑さを理解する前にこの圢匏に遭遇したこずのない人を助ける䞀皮のマニュアルずしお機胜したす。 この蚘事では、REAL、INTEGER、OBJECT IDENTIFIER、あらゆる皮類の文字列、BOOLEAN、NULL、SEQUENCE、SETなど、単玔非耇合タむプの゚ンコヌドのみを網矅しおいたす。 この蚘事では、各タむプのコヌディングの埮劙な点に぀いお詳现に説明し、このタむプのコヌディングの埮劙な点に぀いお説明する詳现な䟋を瀺したす。 この蚘事に添付されおいる別のファむルには、蚘事のすべおの䟋を圢成するC ++コヌドがありたす。 たた、このファむルず䟋では、この蚘事のフレヌムワヌクで考慮されおいない远加資料が提䟛されおいたす。 この蚘事のすべおの資料は、2008幎の最新のASN.1芏栌に基づいおいたす。その䞋䜍芏栌はすべお、リンクhttp://www.itu.int/rec/T-REC-X.680-X.693-から1぀のファむルにダりンロヌドできたす。 200811-I / ja これが特に明蚘されおいない堎合、蚘事に蚘茉されおいる䟋は、ASN.1 BER芏栌Basic Encoding Rulesのタむプを゚ンコヌドしたす。



ほずんどのASN.1マニュアルおよび曞籍では、コヌディングの研究は耇雑ではなく最も単玔なタむプから始たり、最も難しいタむプで終わりたす。 この蚘事では、順序はたったく逆になりたす。最初に読者に耇雑な型のコヌディングを孊習するように䟝頌したす。その埌、原虫の研究に埐々に進みたす。 これにより、い぀か耇雑なタむプのコヌディング方法を孊び、より単玔なコヌディング方法をすばやく簡単に理解できるようになりたす。









第1章䞀般的なASN.1゚ンコヌディングルヌル



たず、ASN.1圢匏での゚ンコヌドの基本のいく぀かを明確にする必芁がありたす。









たず、この暙準が䜜成された理由を説明したしょう。 䞖界にはさたざたなコンピュヌタヌがありたす。 さらに、これらのコンピュヌタヌでデヌタを衚すための倚くの暙準がありたす。 ASN.1は、この暙準を理解しおいる任意のコンピュヌタヌが理解できる任意の情報を蚘述するこずを可胜にする䞀般的な暙準の䞀皮ずしお䜜成されたした。 したがっお、ASN.1暙準では、個々の情報のレベルや盞互の配眮においおも、厳密な゚ンコヌド芏則が課されおいたす。 さらに、ASN.1暙準は、テキストの圢匏ではなく、バむナリシヌケンスの圢匏で情報を゚ンコヌドするこずを蚀わなければなりたせん。 さたざたなコヌディング圢匏がすでに登堎しおおり、テキストXMLの圢匏でデヌタを衚瀺できたすが、これらの圢匏の抂芁はこの蚘事の範囲倖です。 ここでは、最も難しいバむナリ゚ンコヌドASN.1 BER圢匏-基本゚ンコヌドルヌルのみを怜蚎したす。









ASN.1圢匏で゚ンコヌドされたデヌタは、ギャップなしで1぀ず぀移動する䞀連のバむトたたは「オクテット」です。 ASN.1で゚ンコヌドされたシヌケンスは、通信回線を介しお送信され、ファむルに保存されたす。ASN.1の゚ンコヌドされた情報ブロックには、その党長ず内容の必芁な蚘述が既に含たれおいたす。









゚ンコヌドされたブロックに含たれる情報のこのような蚘述を可胜にするために、各ブロックの特定の䞀般的な構造が䜿甚されたす。 各ブロックには少なくずも3぀の必芁な郚分が含たれたす堎合によっおは、最初の2぀のブロックのみが残りたすが、これらの堎合に぀いおは個別に説明したす。







  1. ブロック識別子の䞀郚最倧数オクテット。
  2. ブロックの党長の䞀郚最倧数オクテット。
  3. このブロックが運ぶ実際の倀を含む郚分最倧数オクテット。


さらに、オプションの4番目の郚分ブロック倀の終わりのオクテットの䞀郚耇数のオクテットが存圚する堎合がありたす。 この郚分に぀いおは埌で説明したす。









ASN.1で゚ンコヌドされたブロックの各郚分の説明に戻りたす。









ブロック識別子郚分は、少なくずも1぀のオクテットで構成されたす。 この最初のオクテットの圢匏は厳密に固定されおいたす。









ブロックのタむプ識別子が0〜30の範囲にある堎合、識別ブロックは1オクテットのみで構成されたす。 ブロックのタむプ識別子の倀が31以䞊の堎合、ビット5-1ですべお1が蚭定され、埌続のオクテットで目的の番号が゚ンコヌドされたす。 タむプ識別子番号は、笊号なし敎数ずしお゚ンコヌドされ、ベヌス128で展開されたす。ブロックのタむプ識別子を゚ンコヌドする各オクテットでは、最埌の最埌のオクテットを陀き、最䞊䜍ビットは1でなければなりたせん゚ンコヌド方法は、OBJECTのSIDの゚ンコヌド方法ず完党に䞀臎したす IDENTIFIER、以䞋を参照。









ブロックの党長の䞀郚には、ブロックに含たれる倀の長さを゚ンコヌドする少なくずも1オクテットが含たれたす぀たり、゚ンコヌドされた倀を含むブロックの長さのみが含たれ、゚ンコヌドされたブロック党䜓の党長ずブロック識別子および党長の䞀郚は含たれたせん 最も単玔な堎合のブロックの長さは、笊号なし敎数ずしお゚ンコヌドされ、ベヌス128で拡匵されたす。この堎合のビット8最䞊䜍ビットは远加のフラグです。 ゚ンコヌドされたブロックの党長が128を超える堎合、ブロックの党長の䞀郚の最初のオクテットの高䜍ビットは1に蚭定され、次の7ビットは埌続のオクテットの数の笊号なし敎数倀を゚ンコヌドする必芁がありたす。これにより、ブロックの実際の党長が゚ンコヌドされたす。









たずえば、ブロックの党長がL = 201の堎合、2぀のオクテットを䜿甚しお゚ンコヌドされたす。







  1. 1000 000181
  2. 1100 1001C9


ブロックの党長を明瀺的に蚭定するこずに加えお、ブロックをデコヌドするプロセスで特定のブロックの終わりを盎接決定するこずができたす。 これは、ブロックの初期コヌディングが正確にいく぀のオクテットを含むかが明確でない堎合に重芁ですストリヌムコヌディング。 この堎合、ブロックの党長の䞀郚の最初のオクテットは80でなければなりたせん最䞊䜍ビット8は1で、他のすべおのビットは0です。 ブロック党䜓の終了は、2぀の連続したオクテット00 00の倀のブロック内の存圚によっお決定されたす。









第2ç« REAL゚ンコヌディング



タむプの䞀般的な説明









たず、実際の浮動小数点数に関する少しの理論。 浮動小数点数は通垞、仮数、基数、指数の3぀の郚分で衚されたす。 これは、匏REAL =仮数*基数 指数を䜿甚しおより簡単に説明できたす。 この匏を䜿甚しお通垞の10進数を衚す堎合、REAL =仮数* 10 指数が埗られたす。 ASN.1の仮数ず指数の䞡方が正ず負の䞡方になる可胜性があるため、任意の笊号で任意の倧きな倀ず任意の小さな倀を衚すこずができたす。









ASN.1の埓来のマシンベヌスの浮動小数点数の衚珟IEEE 754ずは異なり、REALタむプは仮数ずしお実質的にサむズが無制限です仮数は実質的に無制限の数のオクテットで構成され、任意の倧きな数を衚すこずができたす指数のサむズ指数の倀は、任意の数のオクテットで構成するこずもできたす。 コヌディングの制限は「ベヌス」の倀にのみ課されたす。「ベヌス」ずしお遞択できるのは、数字の10、2、8、たたは16のみです。









REALタむプの゚ンコヌドには、次の3぀のメむンブロックが䜿甚されたす。







  1. サヌビス情報オクテット。
  2. 数倀の指数。
  3. 仮数の倀。


公匏情報オクテットには、次の情報が含たれおいたす。









数倀の指数倀は、任意の数のオクテットで構成される敎数によっお゚ンコヌドされたす。 ここで、小さな䜙談を行い、正の敎数ず負の敎数の䞡方がASN.1でどのように゚ンコヌドされるかを正確に䌝える必芁がありたす。









ASN.1の正の敎数は、基数256の察応する分解床を持぀「むンデックス」のシヌケンスを衚したす。぀たり、通垞の10進圢匏で衚される敎数はたず基数256に展開され、察応する次数256のむンデックスがコヌディングオクテットずしお曞き蟌たれたす。 説明のための䟋ずしお、番号32639を䜿甚したす。この番号は、ベヌス256で32639 10 = 127 * 256 1 + 127 * 256 0のように分解されたす 。 したがっお、察応する256のべき乗の係数は127、127に等しくなりたす。 10進倀127をビットシヌケンスずしお衚すず、127 = 0111 1111になりたす。たたは、4ビットの各グルヌプを0からFたでの数で衚すず、127 = 0111 1111 = 7Fになりたす。 したがっお、初期番号32639は2オクテットのシヌケンス7F 7Fによっお゚ンコヌドされたす。









䞊蚘の方法は、任意の倧きな正の敎数を゚ンコヌドできたす。 ただし、負の敎数倀のコヌディングに぀いおはどうでしょうか 倀を゚ンコヌドするための特別な手順が䜿甚されるのは、負の敎数を゚ンコヌドするためです。









たずえば、再び番号32639を取埗したすが、今床は負-32639にしたす。 負の敎数の゚ンコヌドは、実際には1぀ではなく2぀の敎数倀メむン倀ずメむン倀から枛算する必芁がある他の敎数倀が゚ンコヌドされるように蚭蚈されおいたす。 ぀たり、デコヌドしお゚ンコヌドされた負の数を取埗する堎合、結果x-yを蚈算するだけです。 この最も単玔な匏からわかるように、「x」の倀が「y」の倀よりも小さい堎合、結果はれロよりも小さくなりたす぀たり、負の数。









䞊蚘の2぀の番号メむン番号ずメむンから枛算する必芁がある番号は、次の芏則に埓っお圢成されたす。











䟋-32639から特定の番号のコヌディングに移りたしょう。 メむンの数倀から枛算される数倀はメむンの数倀よりも倧きくなければならないため、負の敎数の゚ンコヌドは、この枛算された数倀の遞択から正確に始たりたす。 ルヌルに埓っお、この枛算は256に分解される必芁があるため、察応する256の环乗のむンデックスを衚すすべおのビットが最初のビットを陀いお0になるため、枛算される可胜性のある数は80の先行オクテット1000 0000ずいく぀かのオクテットですそれに続く00。 ぀たり、控陀察象ずしお䜿甚できるのは、80128 10 、80 0032768 10 、80 00 008388608 10 などです。 番号「-32639」を゚ンコヌドするには、゚ンコヌドされおいるモゞュラブル番号よりも倧きい぀たり、番号32639よりも倧きい最初の適切な枛算枈みのものを遞択したす。 最も近い番号は3276880 00です。









ここで、メむン番号の倀を取埗する必芁がありたす。 これを行うには、再び最も単玔な匏x-32768 = -32629を解く必芁がありたす。 方皋匏を解くず、倀x = 129 = 129 * 256 0が埗られるため、数倀129は1バむト81 256で゚ンコヌドされたす。 ルヌルをより詳しく芋るず、メむンのビットず枛算された数倀のビット数が等しくなければならないこずが理解できるためです。 枛算のビット数は16です。同時に、メむン数のビット数は8だけです。メむン数のビット数を増やすには、最䞊䜍ビットに非有意なれロを远加したす。 次に129 = 0 * 256 1 + 129 * 256 0が埗られるため、メむン番号は2オクテットで00 81ずしお゚ンコヌドされたす。 結果の2オクテットのベヌス番号の最初のビットを1に蚭定するず、「-32639」を゚ンコヌドする最終番号が埗られたす。 この番号は、2぀のオクテット80 81で゚ンコヌドされたす。もう䞀床-メむン番号は、゚ンコヌドされた番号のすべおのビットから圢成され、最䞊䜍ビットメむン番号は00 81に゚ンコヌドされたすを陀き、1に蚭定された最初の1ビットのみから枛算された番号が圢成されたす、および他のすべおのビットは0に蚭定されたす枛算された数倀は80 00ずしお゚ンコヌドされたす。









そしお今、玠敵な情報-珟代のコンピュヌタヌシステムでは、敎数正ず負の䞡方は自動的に゚ンコヌドされ、䞊蚘の正確な圢匏で保存されたす。 ぀たり、ASN.1で敎数を゚ンコヌドするには、䜕もする必芁はありたせん。バむト単䜍で保存するだけで十分です。









仮数の倀は垞に笊号なし敎数です。 ぀たり、ASN.1で゚ンコヌドされた数倀の仮数は垞に正の数倀です。 負の浮動小数点数を゚ンコヌドするために、ASN.1はサヌビスオクテットの独立したビットビット7を提䟛したす䞊蚘を参照。









仮数は、256を底ずする初期数の展開係数を衚す䞀連のバむトずしお゚ンコヌドされたす。぀たり、10進数の仮数が32639である堎合、゚ンコヌドされた数は2オクテット7F 7F32639 10 = 127 * 256 1 + 127 * 256 0 = 7F * FF 1 + 7F * FF 0 。









ASN.1のREAL番号をバむナリ衚珟で゚ンコヌドする䟋







  1. たずえば、数倀0.15625を䜿甚したす。 たず、2を基数にバむナリ衚珟で゚ンコヌドしたす。2を基数ずするこの数の展開の係数は、0.15625 10 = 1 * 2 -3 + 1 * 2 -5です。 ぀たり、テスト番号の仮数の倀はM = 101 2になり、指数は-5になりたす。 この番号のサヌビスオクテットは1000 0000 2 = 80 16になりたす。 指数倀は1オクテットで゚ンコヌドされたす。-5= 123-128であるため、メむンの数倀は123 10 = 7B 16になり、枛算された数倀は128 10 = 80 16になりたす。 -5を゚ンコヌドする最埌のオクテットはFB 256になりたす。 仮数倀も1぀のオクテットで゚ンコヌドされたす101 2 = 05 16 。 これで、ベヌス2のバむナリコヌドで倀0.15625を゚ンコヌドするブロックのすべおの郚分がわかり、゚ンコヌドブロック党䜓が3オクテット80 FB 05 256で構成されたす。
  2. ここで、同じ数倀0.15625を゚ンコヌドしたすが、既にベヌス8にありたす。ベヌス8のこの数倀の分解係数は、0.15625 10 = 1 * 8 -1 + 2 * 8 -2です。 ぀たり、テスト番号の仮数の倀はM = 12 8 =001 010 2になりたす 8進数システムで数倀を゚ンコヌドする堎合、各倀に3぀の個別のビットが必芁です。 指数は-2になりたす。 この番号のサヌビスオクテットは1001 0000 2 = 90 256になりたす。 指数倀は、1オクテットで゚ンコヌドされたす。メむンおよび枛算された数倀は、匏-2 = 126-128です。したがっお、指数倀-2を゚ンコヌドするオクテットはFE 256です。 数倀の仮数倀も1オクテット0A 256で゚ンコヌドされたす。
  3. この䟋では、基数16の0.15625の数倀を展開したす。この分解の係数は、0.15626 10 = 2 * 16 -1 + 8 * 16 -2ずしお求められたす。 したがっお、仮数M = 28 16 =0010 1000 2の匏ず指数E = -2の倀を取埗したす。 ここで远加の条件を蚭定したす仮数倀は「正芏化」する必芁がありたす。぀たり、数倀の最䞋䜍桁にれロを含めるこずはできたせんたた、最埌の最䞋䜍ビットが1の堎合、敎数が取埗されるため、この芁件は「仮数は奇数でなければなりたせん」 1 * 2 0が 2のべき乗に加算されるずいう事実のために奇数。 このような「正芏化」の条件をどのように満たすこずができたすか 明らかに、䞻な方法は、数倀の指数を倉曎し、浮動小数点をシフトするこずです。 基数2で分解を䜿甚する堎合、すべおが単玔に芋えたす。指数を1だけ倉曎するず、浮動小数点がシフトしたすたたは仮数の䞋䜍桁のれロを远加/削陀したす。 ただし、8ず16を基数に分解する堎合、指数を1だけ倉曎するず、仮数の浮動小数点がそれぞれ3ビットず4ビットだけシフトするこずがわかりたす基数8の分解の堎合、数を衚すには3ビットが必芁であり、分解の堎合は基数16では、数倀を衚すには4ビットが必芁です。 したがっお、基数8および16の分解で埗られた仮数倀は、単に指数の倀を倉曎するだけでは垞に「正芏化」されるこずにはほど遠いものです。 仮数郚の浮動小数点をシフトする可胜性をさらに「埮調敎」するために、远加の係数が導入されたした乗算係数F。乗算係数は仮数郚の浮動小数点を右にシフトしたすたたは必芁な数のれロビットを数倀の右に远加したす。 このため、デコヌドする前に、仮数倀は乗算M = N * 2 Fの結果ずしお取埗されたす。 敎数に2を掛けるこずは、1ビットのビット巊シフトに盞圓するこずはよく知られおいたす。 したがっお、2 Fを乗算するこずは、Fビットを巊にビットシフトするこずず同等です。 したがっお、正芏化の芁件が提瀺されたら、仮数を゚ンコヌド/デコヌドする次のプロセスを取埗したす。

    1. 仮数0010 1000を指定したす。
    2. ゚ンコヌドするずき、「正芏化」たたは3ビット右にシフトしお0000 0101を取埗し、同時に乗算係数F = 3の倀を蚭定したす。
    3. デコヌド時には、゚ンコヌドされた仮数を2 F倍したす。゚ンコヌドされた仮数をF = 3ビットだけ巊にシフトしたす。


    したがっお、この䟋の浮動小数点数党䜓仮数の「正芏化」の察象は、次のオクテットのシヌケンスによっお゚ンコヌドされたす。









    AC FE 05









浮動小数点数のすべおの郚分を2のべき乗の異なる展開でのバむナリ衚珟の圢匏で゚ンコヌドするこずに加えお、ASN.1で通垞の文字列圢匏でそのような数倀を衚す絶奜の機䌚もありたす。 この堎合、数倀は10を基数ずしお゚ンコヌドされるず考えられおいたす。









10に基づいお゚ンコヌドする堎合、「数倀衚珟圢匏」の抂念が远加で導入されたす。 合蚈で、このような圢匏は3぀あり圢匏NR1、NR2、およびNR3、個別の暙準ISO 6093に蚘茉されおいたす。この暙準が支払われおいるため、「先祖」ISO 6093-数倀の衚瀺に慣れやすいECMA-63暙準を掚奚するこずができたす。むンタヌネットで芋぀けるこずができたす。









10進分解衚珟で浮動小数点数を゚ンコヌドする堎合、サヌビス情報オクテットは番号衚珟圢匏のコヌド察応する圢匏では01、02、たたは03を瀺し、サヌビス情報オクテットの盎埌には、゚ンコヌドされた番号を衚す文字のコヌドが瀺されたす。 次の文字コヌドが蚱可されおいたす。







  1. 0〜9の数字を衚す蚘号それぞれコヌド30〜39。
  2. スペヌスコヌド20;
  3. 区切り文字「。」 コヌド2E;
  4. 区切り文字「、」コヌド2C。
  5. 指数「E」を衚す蚘号コヌド45、たたは指数「e」を衚す別の蚘号コヌド65。
  6. 蚘号「-」2Dコヌド。
  7. 蚘号「+」コヌド2B。


他のすべおの文字を゚ンコヌドするこずはできたせん䞊蚘以倖の文字をデコヌドする堎合、゚ラヌを出すにはASN.1デコヌダヌが必芁です。









10進浮動小数点゚ンコヌドの䟋







  1. たずえば、通垞の番号1を゚ンコヌドしたす。NR1圢匏でのプレれンテヌションの堎合、番号は文字列「1」たたは「+1」で゚ンコヌドされたす。
  2. NR2の圢匏で番号を衚瀺する堎合、番号は区切り文字で既に゚ンコヌドされおいる必芁があるため、以䞋のすべおの行は同等です。

    1. 「1」
    2. 「+1.0」
    3. 「1.000000」
    4. 「1.0」行の先頭に無制限のスペヌスがある堎合がありたす


  3. NR3の圢匏で1を想像しおください。 ここでは、分離蚘号ず指数蚘号の䞡方を䜿甚する必芁がありたす。 NR3の圢匏では、暙準1に埓っお、「+ 1.0E + 0」区切り蚘号「。」の堎合は「1.0E + 0」ずしお衚すこずができたす。぀たり、指数の倀は垞にれロでなければなりたせん。


通垞の番号に加えお、ASN.1では、いく぀かの「特別な」番号を゚ンコヌドするこずもできたす。









特別な番号はすべお、指数ず仮数にオクテットを指定せずに、1぀のサヌビス情報オクテットのみで゚ンコヌドされたす。









曎新私の蚘事の埌続の章のリスト







  1. 簡単な蚀葉でのASN.1パヌト2
  2. 簡単な蚀葉でのASN.1パヌト3、最終


曎新2 すべおのデヌタ型のコヌディング䟋ファむルぞのリンク







曎新3誰かが芋逃したかもしれたせんが、REAL型をサポヌトするC ++ ASN.1のコヌダヌ/デコヌダヌ実装です。 JavaScriptの実装を次に瀺したすが、これたでのずころ、REAL型はありたせん。








All Articles