1

IP4 ネットワーク マスク (/19 のような CIDR ブロック サイズに対応) の 1 ビットの数を表す 0 ~ 32 の入力が与えられると、

  1. それを 4 バイト長のネットマスクに変換するエレガントな方法
  2. それを 4 バイト長のネットマスクに変換する簡単な方法

プロトタイプ:

Function NetMaskFromBitCount(BitCount As Long) As Long
   'Logic here '
End Function

これは、VB6 が unsigned を実行しないという事実によって複雑になることに注意してください。そのため、通常の数学のトリックではうまくいかないことがよくあります。(Number And &H80000000)がゼロでない場合Number \ 2、SHR 操作と同じにはなりません。

いくつかの方法を思いつきましたが、それらはエレガントではないと思いますし、おそらくそれほど高速でもありません。

私が持っていたアイデアの 1 つは、非常に高速な CopyMemory API を戦略的に使用することです。過去に、Long をバイト (0 から 3) にブラットし、必要に応じて各部分を処理することで、署名付き/未署名の Long の問題を解決しました。

私は inet_ntoa() および inet_addr() Windows API 関数も使用しており、これらは逆バイト順で IP シリアル番号を返すため、逆順でバイトを返すソリューションは優れています (私はすでに、必要に応じてバイト順ですが、それを避けるのも良いでしょう)。

例:

Input = 2
Output = -1073741824 (&HC0000000)
Alternate Output = 12 (&HC0, reverse byte order)

Input = 19
Output = -8192  (&HFFFFE000)
Alternate Output = 14745599 (&H00E0FFFF, reverse byte order)

実用的なソリューションは優れていますが、私が探しているのは ELEGANT または FAST です。

4

3 に答える 3

1
Function NetMaskFromBitCount(ByVal lBitCount As Long) As Long
    If lBitCount > 0 Then
        NetMaskFromBitCount = -1 * 2 ^ (32 - lBitCount)
    End If
End Function

このパラメータを作成する必要がありましたByVal!

テストは次のようになります。

Debug.Assert NetMaskFromBitCount(19) = &HFFFFE000
Debug.Assert NetMaskFromBitCount(2) = &HC0000000
Debug.Assert NetMaskFromBitCount(32) = &HFFFFFFFF
Debug.Assert NetMaskFromBitCount(0) = 0
于 2010-02-20T10:53:50.420 に答える
1

可能な入力は 32 個しかないため、配列からの 32 個の出力すべてを参照するルックアップ テーブルが最速のソリューションになると思います。エレガンスのポイントを獲得しません。警告:エアコード

Function DoIt(ByVal Input As Long) As Long  
  Static lArray() As Long  
  Static bInitialised As Boolean   
  If Not bInitialised Then   
    ReDim Preserve lArray(0 To 31)   
    lArray(0) = 0   
    lArray(1) = &H80000000    
    lArray(2) = &HC0000000    
    ' etc... '  
    bInitialised = True 
  End If
  DoIt = lArray(Input)  ' for bonus marks raises an error on illegal input ' 
End Function  

より一般的なものが必要な場合は、VBSpeed には、高速な VB6 左シフトの長年にわたるオープンな競争があります。

  • これは現在の勝者で、VB6 でインライン アセンブラShiftLeft04を取得するために恐ろしい、申し訳ありませんが素晴らしいトリックを使用しています。笑って、泣いて、恐怖で叫ぶ…
  • 現在次点のShiftLeft06は、約 200 行のすべてネイティブな VB6 です。1.3 倍の時間がかかりますが、それでも高速です。
于 2010-02-20T12:25:41.173 に答える
0

私はVB6を持っていませんが、.Netでそれを行う方法は次のとおりです

    Const allBroadcast As Integer = Integer.MaxValue ' = 2,147,483,647
    Dim mask As Integer
    'three examples
    mask = allBroadcast << (32 - 24) '/24
    mask = allBroadcast << (32 - 16) '/16
    mask = allBroadcast << (32 - 8) '/8
于 2010-09-20T11:22:28.090 に答える