将十进制字符串 IP 掩码转换为带尾随零的无符号整数

Convert decimal string IP mask to unsigned int with trailing zeros

我得到一个掩码作为字符串,我使用 strtolstrtok 检索它,我想保存在 unsigned int x 中,尾部带零,并且 & 它的 IP 也表示为 unsigned int,以便仅保留 MSB(最后我将将该 IP 与另一个 IP 进行比较)。

我的想法是设置x的所有位,然后关闭掩码大小之后的所有位:

#define IPV4_LENGTH 32

//subent is "123.34.45.66/31"

curr_IP->address = malloc(sizeof (struct in_addr));
token = strtok(subnet, "/");
inet_aton(token, curr_IP->address);
long mask  = strtol(strtok(NULL, "/"), NULL, 10);
curr_IP->x = -1;
for(long i=mask; i<=IPV4_LENGTH; i++){
    curr_IP->x &= ~(1U << i);
}

示例:如果 mask = 31,我想以 11111111111111111111111111111110 结束,在 unsigned int -> FFFFFFFE 中表示为 HEX

P.S掩码不能为0

更新: curr_IP->x = -1;

后的内存查看

我们可以看到它确实设置了所有位

i = 31

curr_IP->x &= ~(1U << i); 之后的内存视图

预计fffffffe

我选择了不同的方法;关闭掩码,然后将相关位设置为 1。

long mask  = strtol(strtok(NULL, "/"), NULL, 10);
curr_IP->x = 0; //mask to 0
for(long i=IPV4_LENGTH - mask; i<IPV4_LENGTH; i++){
    curr_IP->x |= (1U << i); //Sets the ith bit of the mask
}

编辑:正如 Morten Jensen 指出的那样,最好不要混合使用有符号和无符号整数,因此更正后的代码如下所示:

unsigned long mask  = strtol(strtok(NULL, "/"), NULL, 10);
curr_IP->x = 0; //mask to 0
for(unsigned long i=IPV4_LENGTH - mask; i<IPV4_LENGTH; i++){
    curr_IP->x |= (1U << i); //Sets the ith bit of the mask
}

此外,我自己调试代码时遇到了困难,因为我使用了内存视图,但没有意识到我应该从从右到左阅读它.

在图片 #2 中,我以为我得到了 fffffff7,但实际上是 7fffffff