1

给定 0 到 32 的输入,表示 IP4 网络掩码中的一位数(对应于 /19 中的 CIDR 块大小),什么是

  1. 一种将其转换为四字节长网络掩码的优雅方法
  2. 一种将其转换为四字节长网络掩码的快速方法

原型:

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

请注意,由于 VB6 不做无符号运算,这很复杂,因此常规的数学技巧通常不起作用。如果(Number And &H80000000)为非零,则Number \ 2与 SHR 操作不同。

我想出了一些方法,但我不认为它们很优雅,而且它们可能没有那么快。

我的一个想法是战略性地使用 CopyMemory API,它非常快。我过去解决了一些有符号/无符号的 Long 问题,只需将 Long 放入一个字节(0 到 3)并根据需要处理每个部分。

由于我还在使用 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)

可行的解决方案很好,但我正在寻找优雅或快速的解决方案。

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 左移公开竞争。

  • 这是当前的获胜者ShiftLeft04,它使用了一些可怕的、抱歉我的意思是出色的技巧来获得VB6 中的内联汇编程序。你会笑,你会哭,你会惊恐地尖叫……
  • 目前的亚军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 回答