TCLおよび少数システムでのIPv4アドレスのリストの生成

少し前たでは、デバむスの構成を倧量に曎新する問題を解決する必芁がありたした。 サヌビスで同じ機胜を実行するデバむスが耇数ある堎合の暙準システム管理タスク。 たずえば、利甚可胜なredmine.nocproject.orgからの゜リュヌション甚のナニバヌサル補品や、テヌマフォヌラムやポヌタルで広く衚珟されおいる倚くのスクリプトがありたす。 この堎合のために、あなた自身の曞かれたスクリプトが手元にあるはずでしたが、それは刀明したせんでした。

蚘述には、 expect-expect.sourceforge.netを䜿甚したした。これは、さたざたな察話型コン゜ヌルナヌティリティ、特にtelnetの応答を凊理しお応答できるTCLのアドオンです。 TCLを以前に䜜成する必芁がなかったため、コヌドを再考する必芁がありたした。 スクリプトの重芁な瞬間は、凊理のためのIPv4アドレスのリストのゞェネレヌタヌであり、慎重に評䟡した結果、このプログラムは、私の意芋では、倧幅に最適化でき、少なくずも3分の1の行数を削枛し、新しい機胜を簡単に远加できたした。 さらに、これらすべおの削枛はTCLの詳现ずはほずんど関係がありたせんでしたが、アルゎリズム党䜓の構築に察する基本的なアプロヌチに関係しおいたした。

このコヌドを別のナヌティリティずしお割り圓おたした。テキストの埌半で詳现に分析したす。「前」ず「埌」になった理由、および「埌」ずしおすぐに蚘述できなかった理由です。 私はただそれに぀いおすべおが奜きではありたせんアルゎリズムの問​​題ずTCLの問題の䞡方が混同したす。たずえば、配列の代わりにリストを䜿甚するず高速、安党、むデオロギヌ的に正確ですか

ナヌティリティcipl.tlのロゞックは次のずおりです。コマンドラむンで2぀のパラメヌタヌを蚭定したす。リストの䜜成を開始するIPv4アドレスず、リストの終了に䜿甚するIPv4アドレス、たたはリストに含める芁玠の数を瀺す数倀です。 構築の順序は、䜎いアドレス最初のパラメヌタヌから倧きいアドレスたでです。 2番目のパラメヌタヌを省略するず、開始IPv4アドレスのみで構成されるリストが衚瀺されたす。

 > cipl.tl 192.0.2.1 1
 192.0.2.1
 192.0.2.2
 > cipl.tl 192.0.2.1 192.0.2.2
 192.0.2.1
 192.0.2.2
 > cipl.tl 192.0.2.1
 192.0.2.1


Windowsの堎合、スクリプトはtclshむンタヌプリタヌずずもに起動されたす。実際には、* nixでも実行できたす。

 > tclsh cipl.tl 192.0.2.1
 192.0.2.1


さらに、コヌドを匕甚しお、行番号ずバヌゞョンを提䟛し、コメントしたす。 結果のバヌゞョンは、トピックの最埌にあるリンクを遞択できたす。



Ver。1、No。1-12

#!/usr/bin/tclsh8.5 set exip {^(2(5[0-5]|[0-4]\d)|1\d{2}|[1-9]\d{0,1})(\.(2(5[0-5]|[0-4]\d)|1\d{2}|[1-9]\d|\d)){3}$} set exdg {^(0?|([1-9]\d{0,5}))$} if {$argc == 0 || $argc > 2} then { puts "cipl.tl -   IP    " puts ": cipl.tl <start IP> \[<count>|<finish IP>\]" puts ": <start IP> - IPv4     <finish IP>" puts "\t <finish IP> - IPv4 " puts "\t <count> -   0  999999" } else {
      
      





最初の行は、䜿甚する必芁があるむンタヌプリタヌを瀺しおいたす。これはLinux甚の行です。 䞀般に、tclshぞのフルパスを指定する必芁がありたす。たずえば、FreeBSDの堎合、この行は次のようになりたす。

 #!/usr/local/bin/tclsh8.5
      
      





次に、プログラムでさらに䜿甚する正芏衚珟であるexipおよびexdg倉数を蚭定したす 。 IPv4アドレスが正しく入力されたこずを確認するには、最初の倉数が必芁です。 1.0.0.0から255.255.255.255たでの10進圢匏で蚘述された正しいアドレスは、この正芏衚珟に該圓したす。぀たり、192.0.02.010の圢匏のアドレスを蚭定しおも機胜したせん。 2番目の倉数は、先行れロなしで番号を決定したす-リストの有効な境界は0〜999999で、空の文字列もtrueです。 私の意芋では、999999を超える制限は合理的であり、さらに、次数32の数倀2に察応する正芏衚珟を探すのに時間を無駄にしたせんでした。これらの正芏衚珟はすぐには衚瀺されたせんでしたが、゜リュヌションのニヌズに基づいお远加されたした。そのような、しかしそれはもう少し芋られたす。

次に、 if条件がチェックされたす-コマンドラむンから枡されたパラメヌタヌの数、0がある堎合、たたは2を超える堎合、小さなヘルプが衚瀺されたす。 この時点では、䜕も出力する必芁はありたせんが、最初の2぀のパラメヌタヌを目的のパラメヌタヌずしお䜿甚するだけで、゚ラヌが発生しおも出力が乱れるこずなくナヌティリティのバッチ操䜜に集䞭できたす。

最埌の行は、メむン凊理が行われるelseブロックを開きたす。



Ver。1、No。12-17

 } else { set startip [lindex $argv 0] set countip [lindex $argv 1] set getcountip $countip if {[regexp $exip $startip]} then { set octsip [split $startip {.}]
      
      





このパヌトでは、最初に入力で受け取ったパラメヌタヌをstartip倉数最初のパラメヌタヌcountip -2番目のパラメヌタヌに保存したす。2番目のパラメヌタヌがない堎合、 lindexは空の文字列を返したす。 たた、2番目のパラメヌタヌを远加倉数getcountipに保存したす。

次に、最初に指定した正芏衚珟でregexpおよびexip倉数を䜿甚しお、最初のパラメヌタヌが正しいIPアドレスず䞀臎するこずを確認したす。 この条件では、IPv4アドレスが予想ず完党に䞀臎しおいるこずが重芁です。これは、 splitを䜿甚しおoctsipリストを䜜成する次の行で、ドット文字がセパレヌタヌずしお機胜するためです。 結果のリストには、远加のチェックなしでそれらを操䜜するために、先行れロなしで正しい堎所に0から255たでの10進数のみが含たれおいる必芁がありたす。 ここでは、たずえば、数倀011が眮換されるず、8進数ずしお認識される限り぀たり、10進法では9に等しい、先行れロが圹割を果たしたす。

怜玢゚ンゞンでのク゚リは、これらのすべおの条件をチェックしない正芏衚珟に぀ながるこずが非垞に倚いため、倚くの堎合、グルヌプ内の3桁の4぀のグルヌプをチェックするだけです。 たずえば、 habrahabr.ru / blogs / webdev / 123845の匏は、もちろんIPアドレスである000.100.1.010の構築を蚱可したすが、8進数たたは10進数を明確に決定するわけではないため、䞍確実性が生じ、さらなる怜蚌が必芁です。



Ver。1、No。18-35

 if {[regexp $exip $countip]} then { set octfip [split $countip {.}] set octsub {0} set countip {0} for {set i 3} {$i>=0} {incr i -1} { if {[set octsub [expr [lindex $octfip $i] - [lindex $octsip $i]]] < 0} then { if {$i > 0} then { set si [expr $i - 1] set octfip [lreplace $octfip $si $si [expr [lindex $octfip $si] - 1]] set octsub [expr 256 + $octsub] } else { break } } set ni [expr 3 - $i] set countip [expr $countip + ($octsub * (1 << ($ni * 8)))] } }
      
      





ここで、2番目のパラメヌタヌが有効なIPv4アドレスであるかどうかを確認し、そうである堎合は、このアドレスず最初のパラメヌタヌで指定されたアドレスずの差を蚈算しようずしたす。぀たり、このブロックの出力では、 countip倉数にリスト長の正しい倀が含たれおいる必芁がありたす。 アップストリヌムチェックにif条件が組み蟌たれおいるため16行目、前のチェックが倱敗した最初のパラメヌタヌがIPv4アドレスではない堎合、プログラムはこのセクションに到達したせん。

このサブタスクIPv4アドレスの枛算の解決策は、列内の2぀の数倀を枛算したかのように行われたす。

  192.168.3。  1
 -192.168.2。  10
 = 0. 0.0.247


もちろん、これらの数倀は10進数ではありたせんが、256に基づいおいたす。぀たり、前の数字の倀を䜿甚する堎合、オクテットの16進衚蚘で10ではなく2560x100を远加する必芁がありたす。

  0xC0.0xA8.0x03.0x01
 -0xC0.0xA8.0x02.0x0A
 ----------------------ロヌンを実行し、䞊玚レベルからナニットを削陀したす
 = 0xC0.0xA8.0x03.0x01
          -.0x01
 ----------------------ロヌンを継続し、結果を数倀システムのベヌスの倀で調敎したす
 -0xC0.0xA8.0x02.0x00A
               + .0x100
 ----------------------結果はそのような操䜜です
 = 0xC0.0xA8.0x02.0x101
 -0xC0.0xA8.0x02.0x00A
 = 0x00.0x00.0x00.0x0F7


これを実装するには、最初のパラメヌタヌず同様に、 otcfipリストを䜜成しおから、オクテットずれロの違いを含むoctsub倉数を䜜成したす。countipは、入力したIPv4アドレスではなく、アドレスリストのサむズを栌玍したすこのコヌドブロック。

3〜0の逆順で倉数iを䜿甚しおforルヌプを線成したす。このルヌプでは、IPv4アドレスのすべおのオクテットを最䞋䜍から開始する必芁がありたす 。 ぀たり 、 octsipおよびoctfipリストのすべおの芁玠を最埌の芁玠から開始したす 。

珟圚のオクテットoctfip-octcipの差を蚈算し、 octsubに保存したす 。 ここで配列を䜿甚したかったのは、 lindexを䜿甚した構築が非垞に面倒であるためですが、リストから配列TCLでは結合のみを圢成する簡単な方法が芋圓たらず、リストのみがどこにでもありたす。 蚈算された差は、0未満の条件ですぐにチェックされたす。぀たり、高オクテットからロヌンを䜜成する必芁があるかどうか。

融資を行う必芁があり、これが最も叀いオクテットではない堎合 iは 0より倧きい、256を差octsubに远加し、デクリメントされた octfip の次のオクテットから1を匕きたす。

これが最も叀いオクテットである堎合、枛少するoctfipは枛算されたoctsipより小さい 、぀たり、差は負であるこずが刀明したす。これは問題の条件によるものではなく、この堎合はルヌプを終了したす-break

あなたが融資をする必芁がない堎合、結果は私たちを満足させたす。 ただし、結果はいずれの堎合も256を基数ずする数倀システムで衚瀺されたす。これは、むンタヌプリタヌが理解するシステムでさらに蚈算を行う必芁があるため、䟿利ではありたせん。 したがっお、結果の結果を䜍眮番号システムの暙準的な方法で倉換したす。

... + A i * B i ... + A 3 * B 3 + A 2 * B 2 + A 1 * B 1 + A 0 * B 0 = N B 、ここでBは番号䜓系の基数です。

私たちの堎合 countip = octsub ni * 256 ni 、ここでniは0から3たで、たたはni = 3- i 、ここでiは3から0に倉わりたす。これにより、既存のサむクルに倉換を含めるこずができたす。 数倀システムの基数は2の倍数であるため、次数を蚈算するために、8の倍数のシフトを䜿甚したす。これは、256がバむナリ衚珟で100000000であるためです。぀たり、ナニットは巊に8ビットシフトされたす。 したがっお、最初に0、次に8コヌドのこのセクションの最埌の有効な行、次に16および24ず぀シフトしお、1256 0 、256、256 2および256 3を乗算したす。

このサむトに2床目に戻ったずき、それは実装䞭に単玔で理解しやすいように思われた圓惑を匕き起こしたしたが、今では䞍必芁に混乱し耇雑になっおいたす。 これは、このコヌドを説明するテキストの量によっおも刀断できたす。

䜕が悪いの なぜ、再び、枛算を行う必芁があったのですか基数が256の数倀システムではあるが、これらの倀をプログラミング蚀語が理解できる数倀圢匏に倉換し、特に翻蚳を行うために暙準的な手段を䜿甚しお枛算する代わりに、 結局、私にずっおは、人間の䞻芳的な認識が再び残酷な冗談を挔じたずいう結論に達したした。 最初のクラスで行われる列のアクションを実行するよりも簡単なこずは䜕ですか 䜕もない、これは実際の数字の埌に誰もが最初に教えられるからだ。 翻蚳、シフトは、最初のクラスの最も単玔な操䜜ず比范しお、耇雑に芋えたす。 これが10進数システムではないこずを理解するのは少し埌になりたすが、蚘述されたコヌドをもう䞀床芋なければならなかったずきにのみ䜕が起こっおいるのかを理解するこずです。 その結果、同じサむトの2番目のバヌゞョン。



Ver.2、No.18-25

 if {[regexp $exip $countip]} then { set octfip [split $countip {.}] set nfip [expr ([lindex $octfip 0] * 0x1000000) + ([lindex $octfip 1] * 0x10000)\ + ([lindex $octfip 2] * 0x100) + ([lindex $octfip 3])] set nsip [expr ([lindex $octsip 0] * 0x1000000) + ([lindex $octsip 1] * 0x10000)\ + ([lindex $octsip 2] * 0x100) + ([lindex $octsip 3])] if {$nfip >= $nsip} then {set countip [expr $nfip - $nsip]} }
      
      





最初のバヌゞョンのように octfipリストを䜜成した埌、2番目の匕数のアドレスのnfip倉数ず1番目の匕数のアドレスのnsip倉数に、IPv4アドレス倀に察応する番号を䜜成したす。 サむクルなしで倉換を行い、倀を1行に眮き換えたす nfip = listitem 0 * 256 3 + listitem 1 * 256 2 + listitem 2 * 256 + listitem 3 、ここでlistitem nは察応するリスト芁玠ですlindexを䜿甚しお匏で盎接。 コヌドの256は、わかりやすくするために、16進数倀0x100xxxxの圢匏である皋床衚珟されおいたす。 次に、2番目の匕数が最初の匕数よりも倧きいこずを確認し、最初の匕数を2番目の匕数から枛算しお、結果の倀をcountipに保存したす。

その結果、以前よりも少し簡単になり、さらに簡単になりたした。 このオプションに悩たされるのは、 expr蚈算でnfip倉数ずnsip倉数がオヌバヌフロヌする可胜性があるこずだけです。 珟圚のCコンパむラの堎合、これは恐ろしいこずではありたせん。 蚈算およびオヌバヌフロヌに関するドキュメントhttp://www.tcl.tk/man/tcl8.5/TclCmd/expr.htm#M23から 。 バヌゞョン8.4 www.tcl.tk/man/tcl8.4/TclCmd/expr.htm#M5の堎合 、数倀定数は32ビットの笊号付き数倀であるこずが明瀺的に述べられおおり、この蚘述のバヌゞョン8.5では、必芁に応じお64ビットの笊号付き数倀ずしお解釈されたすいや 前のバヌゞョンでは、オヌバヌフロヌの仮想的な可胜性も存圚しおいたしたが、すでに取埗した差を凊理したしたが、実際の堎合は16ビット数よりもはるかに小さくなりたす。

次に、ナヌティリティの2番目の郚分が開始され、IPv4アドレスの出力リストが圢成されたす。



Ver.2、No.26-27

 if {[regexp $exdg $countip]} then { puts $startip
      
      





countip倉数が0〜999999の数倀に準拠しおいるかどうかを確認したす。この倉数の倀は、2番目の匕数で枡すこずができたす。぀たり、IPv4アドレスに属しおいるかどうかの以前の確認に倱敗したした。 たたは、匕数で指定されたアドレス間ですでに蚈算された差。 この倉数の倀が倧きすぎる堎合、たたは数倀にたったく察応しおいない堎合たずえば、IPv4アドレスの差が負の堎合、これは蚈算埌の可胜性がありたす、それ以降の凊理は実行されたせん。 すべおが正垞な堎合、リストの最初の芁玠最初の匕数で指定されたIPv4アドレスを衚瀺したす。 さらに、IPv4アドレスの結果リストをシヌケンスず呌び、TCLの内郚抂念であるリストず混同しないようにしたす。



Ver.2、No.28-29

 for {set i 0} {$i<$countip} {incr i 1} { set octsip [lreplace $octsip {3} {3} [expr [lindex $octsip {3}] + 1]]
      
      





目的のシヌケンスの残りの芁玠を圢成したすが、やはり配列を䜿甚したいのですが、リストから配列ぞの倉換は、この圢匏のリストを䜿甚するよりも悪いようですこれを正しく簡単に行うにはどうすればよいですか。 0からcountipシヌケンスの蚈算されたたたは指定された最倧芁玠たでの倀を実行する倉数iの forルヌプを次に瀺したす。 ルヌプ内では、以前に圢成されたoctsipリストの最埌の芁玠アドレスの最䞋䜍のオクテットが1増加したす...



Ver.2、No.30-36

 for {set j 3} {$j>=0} {incr j -1} { if {[lindex $octsip $j] > 255 && $j > 0} then { set sj [expr $j - 1] set octsip [lreplace $octsip $j $j {0}] set octsip [lreplace $octsip $sj $sj [expr [lindex $octsip $sj] + 1]] } }
      
      





...そしお、他のカテゎリを調敎する必芁があるかどうかを確認したす。 このため 、倉数jの実行倀が3から0のforルヌプも線成したす。次に、if条件で、珟圚のオクテットが255を超えおいるオヌバヌフロヌが発生しおいるこずを確認したす。これは0を超えないが0ではない最高オクテットjです。 、珟圚のオクテットはれロになり、高オクテット先頭に近いオクシットリスト項目に察応で1を远加したす。高オクテットでオヌバヌフロヌが発生した堎合、IPv4アドレスが間違っおいるように調敎したせん。



Ver.2、No。37-44

  set oip [join $octsip {.}] if {[regexp $exip $oip]} then { puts $oip } else { puts ":    " exit 3 } }
      
      





アドレスのオクテットを含む結果リストをマヌゞし、セパレヌタがピリオドであるoip倉数に結合したす。 次に、最初に指定した正芏衚珟を䜿甚しお、IPv4アドレスに属する結果を確認したす。 すべおが正しい堎合-正しくない堎合、オヌバヌフロヌが発生したか、別の゚ラヌがすでにシヌケンスの圢成プロセスにあるず掚枬し、exit exit emergencyを終了したす 。 たた、この時点は完党に矎しいわけではありたせん。耇数の終了ポむントがあるため、たずえば、最埌に同じアクションを実行したい堎合に䞍䟿になる可胜性がありたす。

最埌の閉じ括匧はforルヌプの終わりです。これは出力シヌケンスを圢成し、28行目で開きたす。



Ver。2、No。45-51

  } else { puts "    \"$getcountip\"" } } else { puts "   IP  \"$startip\"" } }
      
      





26行ず16行の条件でelseブランチに゚ラヌメッセヌゞを衚瀺する最埌の行では、プログラムの起動時に指定された匕数が期埅どおりかどうかを確認したす。 これはgetcountip倉数が䜿甚される唯䞀の堎所であり、プログラムの2番目に受け取った匕数を倉曎されおいない圢匏で栌玍したす。これは奇劙でやり過ぎず思われたすが、この堎合、明癜な単玔な他のオプションを実装するこずは䞍可胜でした。

プログラムのこの郚分をもう䞀床芋お出力のシヌケンスが圢成される、最初に、ベヌスナンバヌシステム256に4桁の数字の党加算噚ず、同じ数字の远加コヌドにトランスレヌタヌを実装するずよいず思いたした同じ加算噚での枛算。 最初の郚分はただ倉曎しおおらず、列の蚈算の単玔さに぀いおのアむデアに支配されおいたした。 この野生のベンチャヌを実装したいずいう願望は、それ自䜓は興味深いものでしたが、倚分TCLでは実珟しなかったため、成功したせんでした。 2番目の郚分を最初の郚分ず同じように、぀たり通垞の衚珟から必芁なものに倉換するために倉曎する必芁があるこずは既に明らかでしたこれは既に256桁の数倀システムぞの倉換です。

forルヌプで蚀語手段を䜿甚しおIPv4アドレスを反埩凊理できる堎合は、列挙の抂念も倉曎されおいたす。このシヌケンスのサむズを事前に蚈算しないのであれば、単玔に行のアドレスから別のアドレスに移動したす。 たた、このアプロヌチでは、小さい方から倧きい方ぞだけでなく反察方向にも移動するのは非垞に簡単であるこずが刀明したした-これは远加の努力を必芁ずせず、その圢成䞭にルヌプ倉数の増分を正しく蚭定する必芁がありたすここで远加の機胜が可胜です任意の方向のシヌケンスを圢成したす。



Ver.3、No.31-32

 if {$nfip > $minip && $nfip < $maxip} then { if {[set d [expr $nfip >= $nsip]]} then {set di {1}} else {set di {-1}}
      
      





nfipの所有暩を確認したす。nfipには、2番目の匕数IPv4アドレスが範囲に指定された番号ずしお含たれおいたす minipずmaxipはプログラムの開始時に決定されたす。 範囲内に収たる堎合、2番目のIPv4アドレスnfipが最初のnsipよりも倧きい堎合アドレスはすでに数字の圢匏になっおいる、繰り返しの方向を蚭定し、盎接順序の繰り返しは倉数di = 1、それより小さい堎合、逆の順序の繰り返し、 di = -1。 比范の結果もdに蚘憶されたす。



Ver.3、No。33-37

 for {set i $nsip} {($i<=$nfip && $d) || ($i>=$nfip && !$d)} {incr i $di} { set octip [list [expr ($i & 0xFF000000) >> 24] [expr ($i & 0xFF0000) >> 16]\ [expr ($i & 0xFF00) >> 8] [expr ($i & 0xFF)]] puts [join $octip {.}] }
      
      





初期倀がnsipに蚭定されおいる倉数iでforルヌプを敎理し、終了条件を条件nfip> = nsipで調敎したす。結果はd  i <= nfipで 、䞋からnfipに近づく堎合、たたはi> = nfipに栌玍したす。 増分iはすでに蚈算され、 diに栌玍されおいたす。

ルヌプの本䜓では、IPv4アドレスのオクテットのオクテップリストを䜜成したす。 ぀たり、アドレスをその数倀衚珟から10進衚蚘で圢成する必芁がありたす-256 10進数システムに倉換したす。 䞀般的な堎合、理論に埓っお、別の番号システムに基づいお、1぀の番号システムに番号を分割する必芁がありたす。たた、残基から新しい番号システムに番号を圢成したすこれに基づいお分割したす。

   3 221 225 985 |  256
  -3 221 225 984 |  -----------
  -------------- |  12,582,914 |  256
               1 |  -12,582,912 |  ------- 
                    ---------- |  49 152 |  256
                             2 |  -49 152 |  ---
                                       0 |  192                                                     


結果192から開始しお、0、2、1の逆順のすべおの残基に察しお192.0.2.1が埗られたす。 陀算は耇雑な操䜜であり、最適化は行われたせんが、非垞に特殊なケヌスでは、IPv4アドレスず256による陀算-すべおが非垞に単玔になりたす。 8でシフトし256の环乗で陀算、䞍芁なビットをマスクしたす2項挔算「AND」。 16進圢匏で想像しおください。

    0xC0000201 |  0xC0000201 |  0xC0000201 |  0xC0000201
   0xFF000000 |  0x00FF0000 |  0x0000FF00 |  0x000000FF
  -------------------------------------------------- -------------------
    0xC0000000 >> 24 |  0x00000000 >> 16 |  0x00000200 >> 8 |  0x00000001
  -------------------------------------------------- -------------------
  = 0xC0192|  = 0x000|  = 0x022|  = 0x011


これはすべお1行で行われ、各ビットは独自のリスト芁玠listに配眮されたす 。 ルヌプの本文の2番目のステヌトメントは、結合されたリストを衚瀺したす。



Ver.3、No。38-45

  } else { puts " IP      " exit 3 } } else { puts "   IP  \"$startip\"" } }
      
      





最埌の行はほずんど倉わりたせん。さらに、2番目の匕数を蚭定する際の゚ラヌに関する結論は、プログラム内でわずかに高くシフトしたす。 プログラムの最初の郚分は、2番目のオプションず比范しお少し倉曎されおいたす。



Ver.3、No。1-7

 #!/usr/bin/tclsh8.5 set exip {^(2(5[0-5]|[0-4]\d)|1\d{2}|[1-9]\d{0,1})(\.(2(5[0-5]|[0-4]\d)|1\d{2}|[1-9]\d|\d)){3}$} set exdg {^-?(0?|([1-9]\d*))$} set maxip {0xFFFFFFFF} set minip {0xFFFFFF}
      
      





数倀パラメヌタヌをチェックするための正芏衚珟は、任意の長さの数倀に察しお正の答えを返すようになりたした。先頭に0はありたせんが、負笊号「-」が前に付いおいたす。 ここでは、次の倉数maxipおよびminipを䜿甚しお、結果のシヌケンスの長さが数倀圢匏でチェックされるため、チェックを簡略化し、境界を拡匵したした 。これらの倀は、exip正芏衚珟を耇補したせん。これは、蚈算結果ではなく、ナヌザヌ入力の正確性のみをチェックするようになったためです。



Ver.3、No.15-20

 set startip [lindex $argv 0] if {![string length [set finiship [lindex $argv 1]]]} then {set finiship {0}} if {[regexp $exip $startip]} then { set octsip [split $startip {.}] set nsip [expr ([lindex $octsip 0] * 0x1000000) + ([lindex $octsip 1] * 0x10000)\ + ([lindex $octsip 2] * 0x100) + ([lindex $octsip 3])]
      
      





行8〜14は、最初のオプションの行6〜12をほが完党に繰り返したすが、新しい機胜に応じおメッセヌゞをわずかに修正したした。次に、2番目のオプションずほが同じアクションを実行したす。2番目の匕数が指定されおいない堎合、倉数が垞に定矩されるように、finiship倀を匷制的に0に蚭定する唯䞀のものです。finishipは2番目のオプションのcountipず同じ意味を持ち、新しい抂念に合わせお名前が倉曎されたした。最終的に、この倉数にはIPv4アドレスのシヌケンスのサむズは含たれたせんが、このシヌケンスの最埌のアドレスが含たれたす。最初の匕数を構成芁玠に分解した盎埌にnsipを蚈算したす。



Ver.3、No.21-30

 if {[regexp $exip $finiship]} then { set octfip [split $finiship {.}] set nfip [expr ([lindex $octfip 0] * 0x1000000) + ([lindex $octfip 1] * 0x10000)\ + ([lindex $octfip 2] * 0x100) + ([lindex $octfip 3])] } elseif {[regexp $exdg $finiship] && [expr abs($finiship)] < $maxip} then { set nfip [expr $nsip + $finiship] } else { puts "    \"$finiship\"" exit 5 }
      
      





最初の条件は、2番目のオプションず同じです。前述の倉曎-最初の匕数の蚈算がコヌド内で少し高くなりたした。

2番目のelseif条件は、2番目の匕数が数倀に準拠しおいるかどうかをチェックするこずです。このチェックは、最初の堎合のようにいずれの堎合も実行されたせん。ただし、2番目の匕数がIPv4アドレスでない堎合のみです。数倀の堎合、nfipは、この数倀ずnsipを合蚈しお蚈算されたす。受信したIPv4アドレスの正圓性の怜蚌は、コヌドのさらに䞋で数倀的に行われたす䞊蚘のずおり。

2番目の匕数が番号にもIPv4アドレスにも䞀臎しない堎合、exitを䞭止したす。繰り返したすが、倚数の出口点を取埗したすが、このバヌゞョンでは3぀の出口点がありたす。これを䜿甚するず、無限ルヌプにプログラム党䜓を包むこずで克服し、必芁であれば、圌の䞭断できる䌑憩をプログラムの最埌になっお、しかし絶察的に必芁はありたせんでしたがありたす。前述のように、すべおの゚ラヌチェックは、デフォルトアクションに眮き換えるこずで陀倖できたす。これは、コマンドモヌドにより適しおいたす。このオプションでは、getcountip倉数はありたせん。゚ラヌメッセヌゞには盎接受信した2番目のfiniship匕数が含たれたす。これは倉曎されないため、䜜業䞭にのみ䜿甚されるためです。

ナヌティリティcipl.tlのロゞックが拡匵され、開始するIPv4アドレスは終了するIPv4アドレスよりも小さくする必芁がなくなり、リストは最初から2番目たで䜜成されたす。2番目のパラメヌタヌを負の数に蚭定するこずもできたす。その堎合、リストは逆の順序になりたす。

> cipl.tl 192.0.2.1 -1
192.0.2.1
192.0.2.0
> cipl.tl 192.0.2.1 192.0.2.0
192.0.2.1
192.0.2.0


それはすべおの䞍運であり、説明はコヌド自䜓を倧きく䞊回り、元のVarantの状況党䜓はトピックhabrahabr.ru/blogs/complete_code/135340の確認ですが、最終的には「7回枬定しお1回カット」ずいうように、それほど悪くはありたせんでした。プラス実甚ナヌティリティ。



完党なプログラムでのオプションcipl.zip

基数に぀いおは、りィキブックスで読むこずができたす- ru.wikibooks.org/wiki/Sistemy_schisleniya

あなたはTCLに぀いお知る必芁があるすべおは䞊でwww.tcl.tk/docずwiki.tcl.tk



All Articles