网络掩码在C ++中转换为CIDR格式

时间:2011-07-11 22:30:55

标签: c++ networking

我必须将2个DWORD,IP地址和网络掩码转换为CDIR格式... 所以我有2个DWORD对应1.1.1.1和255.255.255.255我想拿出字符串 1.1.1.1/32

对此有何想法?

由于

5 个答案:

答案 0 :(得分:3)

前缀长度等于子网掩码的二进制表示中的(前导)数量。所以你只需要计算(领先)的数量。

答案 1 :(得分:3)

由于有一小部分固定数量的有效网络掩码(确切地说是32),最快的方法可能就是在初始化时只构建一个掩码映射到前缀长度,并且转换只是一个查找地图。

答案 2 :(得分:2)

最简单的方法:

  static unsigned short toCidr(char* ipAddress)
  {
      unsigned short netmask_cidr;
      int ipbytes[4];

      netmask_cidr=0;
      sscanf(ipAddress, "%d.%d.%d.%d", &ipbytes[0], &ipbytes[1], &ipbytes[2], &ipbytes[3]);

      for (int i=0; i<4; i++)
      {
          switch(ipbytes[i])
          {
              case 0x80:
                  netmask_cidr+=1;
                  break;

              case 0xC0:
                  netmask_cidr+=2;
                  break;

              case 0xE0:
                  netmask_cidr+=3;
                  break;

              case 0xF0:
                  netmask_cidr+=4;
                  break;

              case 0xF8:
                  netmask_cidr+=5;
                  break;

              case 0xFC:
                  netmask_cidr+=6;
                  break;

              case 0xFE:
                  netmask_cidr+=7;
                  break;

              case 0xFF:
                  netmask_cidr+=8;
                  break;

              default:
                  return netmask_cidr;
                  break;
          }
      }

      return netmask_cidr;
  }

答案 3 :(得分:1)

这不是完全可移植的,但是如果您的程序运行在支持Intel指令集的芯片上,则可能是最快的方法。 (并且类似的方法可能适用于其他体系结构)。英特尔芯片具有称为POPCNT的指令,该指令返回变量中设置为1的位数。大多数编译器应提供访问此内容的内在函数。例如,Microsoft编译器给您__popcnt,而GCC给您__builtin_popcount。 (具有不同的参数大小的不同风格)。

假设掩码格式正确(如此处提供的所有其他解决方案一样),您可以通过一条机器指令获得CIDR位计数。

inline uint32_t getBitCountFromIPv4Mask(uint32_t mask) {
    return __builtin_popcount(mask);    // presumes a well-formed mask.
}

您也可以使用IPv6掩码来执行此操作。有POPCNT的64位版本,但是由于in6_addr不会给出64位块中的地址片段,因此最好不要在这里使用它。

uint32_t getBitCountFromIPv6Mask(const in6_addr &mask) {
    uint32_t bitCount = 0;

    for (uint32_t ii = 0; ii < 4; ii++) {
        bitCount += __builtin_popcount(mask.s6_addr32[ii]);
    }

    return bitCount;
}

答案 4 :(得分:0)

如果你有大量的这些要做,效率不高,因为它一次只能通过一个位。但是非常简单的方法来计算网络掩码中的每个位:

int cidr = 0;
while ( netmask )
{
    cidr += ( netmask & 0x01 );
    netmask >>= 1;
}

然后将IP地址与此CIDR值组合。