VB6 IP4-根据位数计算净掩码(长)

VB6 IP4-根据位数计算净掩码(长),vb6,performance,ip-address,bit-manipulation,cidr,Vb6,Performance,Ip Address,Bit Manipulation,Cidr,如果输入值为0到32,表示IP4网络掩码中的一位数(对应于CIDR块大小,如/19所示),那么 将其转换为四字节长的网络掩码的优雅方式 一种将其转换为四字节长网络掩码的快速方法 原型: Function NetMaskFromBitCount(BitCount As Long) As Long 'Logic here ' End Function Input = 2 Output = -1073741824 (&HC0000000) Alternate Output = 12 (

如果输入值为0到32,表示IP4网络掩码中的一位数(对应于CIDR块大小,如/19所示),那么

  • 将其转换为四字节长的网络掩码的优雅方式
  • 一种将其转换为四字节长网络掩码的快速方法
  • 原型:

    Function NetMaskFromBitCount(BitCount As Long) As Long
       'Logic here '
    End Function
    
    Input = 2
    Output = -1073741824 (&HC0000000)
    Alternate Output = 12 (&HC0, reverse byte order)
    
    Input = 19
    Output = -8192  (&HFFFFE000)
    Alternate Output = 14745599 (&H00E0FFFF, reverse byte order)
    
    请注意,由于VB6不执行无符号操作,因此常规的数学技巧通常不起作用,这一点很复杂。如果
    (Number And&h8000000)
    为非零,则
    Number\2
    将与SHR操作不同

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

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

    由于我也在使用inet_ntoa()和inet_addr()Windows API函数,它们以相反的字节顺序返回IP序列号,因此以相反的顺序返回字节的解决方案非常好(我已经有了一个函数,可以根据需要翻转字节顺序,但避免这样做也很好)

    示例:

    Function NetMaskFromBitCount(BitCount As Long) As Long
       'Logic here '
    End Function
    
    Input = 2
    Output = -1073741824 (&HC0000000)
    Alternate Output = 12 (&HC0, reverse byte order)
    
    Input = 19
    Output = -8192  (&HFFFFE000)
    Alternate Output = 14745599 (&H00E0FFFF, reverse byte order)
    
    工作解决方案是好的,但优雅或快速是我想要的

    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
    

    您只有32个可能的输入,所以我猜最快的解决方案是引用一个数组的所有32个输出。它不会因为优雅而赢得分数。警告:

    如果你想要更一般的东西,VBSpeed有一个长期的公开竞争

    • 这是目前的赢家,他使用了一些可怕的,对不起,我是说很聪明的技巧来获得VB6中的内联汇编程序。你会笑,你会哭,你会在恐惧中尖叫
    • 目前的亚军是大约200行的所有原生VB6。需要1.3倍的时间,但仍然很快
        我没有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
        
        Const allBroadcast As Integer=Integer.MaxValue'=2147483647
        将遮罩变暗为整数
        "三个例子:
        
        mask=allBroadcast人们使用VB6所做的事情。从你最后一句话的措辞来看,似乎优雅或快速的解决方案不一定奏效!?我确信这是一个疏忽,但为了以防万一,我可以提供
        Output=0&
        。当然,它可能不适用于所有情况,但只需感受优雅和速度即可!:)让我重新措辞。只有有效的解决方案是不够的。工作和优雅或快速是我所寻找的!VB6不允许数组常量。您认为加载阵列以提高速度的最佳方法是什么?一个静态变量可能会有所帮助,或者一个只加载一次变量的Init(),但这会变得更加笨拙。而且,shiftright的东西真的很有趣。我猜你是在建议类似于Not(&hffffffffshr位计数)的东西吗?或者,是否有一个更简单的对应ShiftLeft:&hffffffshl(32位计数)Ooh。我一直认为第一点是个问题。但是这个解决方案观察到,除了输入0之外,所有掩码都是负数(设置了第一位),实际上是两个的负幂。非常有趣。我应该列出所有的价值观,我会立即看到这一点!如果我记得的话,可能不会那么快,VB中的power操作符并不是世界上最快的。但是非常简单和优雅!是的,我不太担心在.Net中执行,因为它有未签名的数据类型和SHL/SHR。