Java 从CIDR符号到IP地址/子网掩码的转换(点十进制) /* *RFC 15181519-无类域间路由(CIDR) *这将从“前缀+前缀长度”格式转换为 *“地址+掩码”格式,例如来自xxx.xxx.xxx.xxx/yy *发送至xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy。 */ 静态私有字符串normalizeFromCIDR(最终字符串netspec) { final int bits=32-Integer.parseInt(netspec.substring(netspec.indexOf('/')+1)); 最终整数掩码=(位==32)?0:0xFFFFFFFF-((1>24&0xFF,10)+“+ 整数.toString(掩码>>16&0xFF,10)+“+ 整数.toString(掩码>>8&0xFF,10)+“+ 整数.toString(掩码>>0&0xFF,10); }

Java 从CIDR符号到IP地址/子网掩码的转换(点十进制) /* *RFC 15181519-无类域间路由(CIDR) *这将从“前缀+前缀长度”格式转换为 *“地址+掩码”格式,例如来自xxx.xxx.xxx.xxx/yy *发送至xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy。 */ 静态私有字符串normalizeFromCIDR(最终字符串netspec) { final int bits=32-Integer.parseInt(netspec.substring(netspec.indexOf('/')+1)); 最终整数掩码=(位==32)?0:0xFFFFFFFF-((1>24&0xFF,10)+“+ 整数.toString(掩码>>16&0xFF,10)+“+ 整数.toString(掩码>>8&0xFF,10)+“+ 整数.toString(掩码>>0&0xFF,10); },java,ip,subnet,james,cidr,Java,Ip,Subnet,James,Cidr,这是apache james中的一个函数,用于将ip转换为指定的格式。请您解释一下函数中发生了什么。与此位移位和转换混淆。 提前感谢。按位操作乍一看可能不是最直观的,但一旦你掌握了它,你就会发现它们很容易理解。我将尝试在172.16.0.1/23的一个示例中解释这段代码作为netspec字符串的作用 第1部分-CIDR到二进制 目标是根据给定的CIDR前缀长度对子网掩码进行二进制表示。CIDR前缀长度只是子网掩码中1位的数目。第一行 /* * RFC 1518, 1519 - Classle

这是apache james中的一个函数,用于将ip转换为指定的格式。请您解释一下函数中发生了什么。与此位移位和转换混淆。
提前感谢。

按位操作乍一看可能不是最直观的,但一旦你掌握了它,你就会发现它们很容易理解。我将尝试在
172.16.0.1/23
的一个示例中解释这段代码作为
netspec
字符串的作用

第1部分-CIDR到二进制 目标是根据给定的CIDR前缀长度对子网掩码进行二进制表示。CIDR前缀长度只是子网掩码中
1
位的数目。第一行

 /*
 * RFC 1518, 1519 - Classless Inter-Domain Routing (CIDR)
 * This converts from "prefix + prefix-length" format to
 * "address + mask" format, e.g. from xxx.xxx.xxx.xxx/yy
 * to xxx.xxx.xxx.xxx/yyy.yyy.yyy.yyy.
 */
static private String normalizeFromCIDR(final String netspec)
{
    final int bits = 32 - Integer.parseInt(netspec.substring(netspec.indexOf('/')+1));
    final int mask = (bits == 32) ? 0 : 0xFFFFFFFF - ((1 << bits)-1); 

    return netspec.substring(0, netspec.indexOf('/') + 1) +
            Integer.toString(mask >> 24 & 0xFF, 10) + "." +
            Integer.toString(mask >> 16 & 0xFF, 10) + "." +
            Integer.toString(mask >>  8 & 0xFF, 10) + "." +
            Integer.toString(mask >>  0 & 0xFF, 10);
}
通过获取
/
的索引并解析继承该索引的整数(在我的示例中为
23
)来查找CIDR前缀长度。此数字从32中减去,以获得子网掩码中的
0
数-这些位也称为主机位

在本例中,我们知道我们正在处理
/23
前缀,它的子网掩码应该如下所示:

n
表示网络(B类网络为16位),
s
表示子网,
h
表示主机。 对于我们来说,网络和子网位在功能上是相同的,但为了准确起见,我做了一个区分。我们的兴趣只是主机位(它的数量)

最简单的方法是将所有
1
s的32位二进制数填入
0
,这就是第二行的位置:

您可以忽略
位==32
检查,因为它不是那么相关,可能只是作为一种优化

减去这些值后,将得到二进制的子网掩码:

  1 << 9                               10 00000000
-      1                                         1
--------------------------------------------------
                                        1 11111111
第2部分-二进制到点十进制 代码的其余部分将二进制值转换为点十进制表示形式-255.255.254.0

(-1 << 9) & 0xFFFFFFFF
return语句由几个串联字符串组成,从IP地址开始,然后是每个八位字节的十进制表示。二进制掩码右移为
(4-n)*8
位(其中
n
是八位字节数)使用二进制和0xFF只得到最后8位,然后由
Integer.toString
解析


结果是
172.16.0.1/255.255.254.0

将cidr表示法转换为二进制的另一种方法:

return netspec.substring(0, netspec.indexOf('/') + 1) +  // part of the netspec string before '/' -> IP address
        Integer.toString(mask >> 24 & 0xFF, 10) + "." +  //                         11111111 & 0xFF = 0xFF
        Integer.toString(mask >> 16 & 0xFF, 10) + "." +  //                 1111111111111111 & 0xFF = 0xFF
        Integer.toString(mask >>  8 & 0xFF, 10) + "." +  //         111111111111111111111110 & 0xFF = 0xFE
        Integer.toString(mask >>  0 & 0xFF, 10);         // 11111111111111111111111000000000 & 0xFF = 0x00
  1 << 9                               10 00000000
-      1                                         1
--------------------------------------------------
                                        1 11111111
  0xFFFFFFFF = 11111111 11111111 11111111 11111111
- (1 << 9)-1 =                          1 11111111
--------------------------------------------------
               11111111 11111111 11111110 00000000
(-1 << 9) & 0xFFFFFFFF
return netspec.substring(0, netspec.indexOf('/') + 1) +  // part of the netspec string before '/' -> IP address
        Integer.toString(mask >> 24 & 0xFF, 10) + "." +  //                         11111111 & 0xFF = 0xFF
        Integer.toString(mask >> 16 & 0xFF, 10) + "." +  //                 1111111111111111 & 0xFF = 0xFF
        Integer.toString(mask >>  8 & 0xFF, 10) + "." +  //         111111111111111111111110 & 0xFF = 0xFE
        Integer.toString(mask >>  0 & 0xFF, 10);         // 11111111111111111111111000000000 & 0xFF = 0x00
input = '1.2.3.4/5'
cidr = input.split('/') 

bin_mask = '1' * cidr + '0' * (32 - cidr)