我必须将2个DWORD,IP地址和网络掩码转换为CDIR格式... 所以我有2个DWORD对应1.1.1.1和255.255.255.255我想拿出字符串 1.1.1.1/32
对此有何想法?
由于
答案 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值组合。