今回は久々にVBA。
ネットワーク学習で苦手なサブネット回りの計算をしてみようと思う。
IPアドレスとサブネットマスクを表記する方法として、プレフィックス長表記(またはCIDR表記)という方法があり、たとえば192.168.1.0/24と書くとIPアドレスが192.168.1.0でサブネットマスクは255.255.255.0という意味になる。
IPアドレスやサブネットマスクの実態は32ビットのデジタルデータ(二進数)で、これを8ビットずつに区切って10進数で表されている。
255.255.255.0はそれぞれ2進数に直すと、11111111.11111111.11111111.00000000となる。このとき1が先頭が24個並んでいるので/24という表記になっているわけだ。
この表記は簡潔に書けて良いんだけど、ネットワークの学習をしているとパッとサブネットに直したいときがある。
これが/8、/16、/24など、都合よくドットの区切り目でわかれているようなケースはナチュラルマスクといって、255か0で構成されるので覚えるのも簡単だが、中途半端な位置で切れていると変換するのもなかなか大変。
ということでVBAコードを書いてみた。
Sub PrefixLengthToSubnetMask() Dim i For i = 0 To 32 Debug.Print "Prefix /" & i, Subnet(i) Next End Sub Function Subnet(prefix) As Variant '最後にJoin使うためにあえて数値ではなくVariantで配列宣言 Dim subnet_(1 To 4) As Variant Dim octet As Integer Dim bit_in_octet As Integer Dim current_bit As Integer For octet = 1 To 4 'Variantなので0で初期化しないとブランク文字になってしまう。 subnet_(octet) = 0 For bit_in_octet = 0 To 7 current_bit = current_bit + 1 If current_bit <= prefix Then subnet_(octet) = subnet_(octet) + 2 ^ (7 - bit_in_octet) End If Next Next Subnet = Join(subnet_, ".") End Function
余談だけど最近はラズパイとかLinuxでのpythonコーディングが増えて変数名はスネークケースの方が読みやすく感じてしまう。
どっぷりVBAに漬かってた頃はキャメル・パスカルが読みやすいと考えていたんだけど、今書いてみると単なる思い込みだった可能性が高いと思い始めた。
当時VB.Netのコーディングガイドライン本だったり、Microsoftのコードだったりを参考にガイドラインを作ったんだけど、現時点ではキャメル・パスカルについては先例を踏襲したという以外にそうする理由を見いだせない。自分で過去に書いたガイドラインから思い切り違反しているのでガイドラインの方を改定してしまいたい気持ちもありつつ、VBAコミュニティはキャメルケースとかパスカルケースが主流だと思われるので悩ましいところ。
さて、実行結果は次のとおり。
Prefix /0 0.0.0.0 Prefix /1 128.0.0.0 Prefix /2 192.0.0.0 Prefix /3 224.0.0.0 Prefix /4 240.0.0.0 Prefix /5 248.0.0.0 Prefix /6 252.0.0.0 Prefix /7 254.0.0.0 Prefix /8 255.0.0.0 Prefix /9 255.128.0.0 Prefix /10 255.192.0.0 Prefix /11 255.224.0.0 Prefix /12 255.240.0.0 Prefix /13 255.248.0.0 Prefix /14 255.252.0.0 Prefix /15 255.254.0.0 Prefix /16 255.255.0.0 Prefix /17 255.255.128.0 Prefix /18 255.255.192.0 Prefix /19 255.255.224.0 Prefix /20 255.255.240.0 Prefix /21 255.255.248.0 Prefix /22 255.255.252.0 Prefix /23 255.255.254.0 Prefix /24 255.255.255.0 Prefix /25 255.255.255.128 Prefix /26 255.255.255.192 Prefix /27 255.255.255.224 Prefix /28 255.255.255.240 Prefix /29 255.255.255.248 Prefix /30 255.255.255.252 Prefix /31 255.255.255.254 Prefix /32 255.255.255.255
ポイントはコード中の以下の部分。
If current_bit <= prefix Then subnet_(octet) = subnet_(octet) + 2 ^ (7 - bit_in_octet) End If
ちょっと分かりにくいと思うのでPrefix /29の場合を例に最後の8オクテットを図示したものを張っておこうと思う。
今後の展望
今回ご紹介したのはIPアドレス・サブネットマスク回りの様々な計算を実行できるクラスモジュールを作りたいという目的の一部分である。
今後記事にするかどうかは分からないけど、とりあえず自分用の計算クラスを作るところまではやってみようと思う。
以上