- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
/*
* 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);
}
这是apache james中的一个函数,可以将ip转换成指定的格式。你能解释一下函数内部发生了什么吗?对这种移位和转换感到困惑。提前致谢。
最佳答案
按位运算乍看之下可能不是最直观的,但一旦您掌握了它,您就会发现它们非常容易理解。我将尝试解释此代码在 172.16.0.1/23
的示例中的作用作为netspec
字符串。
目标是根据给定的 CIDR 前缀长度对子网掩码进行二进制表示。 CIDR 前缀长度只是一个数字 1
子网掩码中的位。第一行
final int bits = 32 - Integer.parseInt(netspec.substring(netspec.indexOf('/')+1));
通过获取/
的索引找到CIDR前缀长度并解析其后的整数(在我的示例中为 23
)。这个数字从 32 中减去得到一个数字 0
在子网掩码中——这些位也称为主机位。
在这个例子中,我们知道我们正在处理 /23
前缀及其子网掩码应如下所示:
n
represents network (16 bits for class B network),s
represents subnet,h
represents host. For us network and subnet bits are functionally the same, but I made a distinction just to be precise. Our interest is just in host bits (number of it).
nnnnnnnn nnnnnnnn sssssssh hhhhhhhh
11111111 11111111 11111110 00000000
做到这一点的最简单方法是拥有所有 1
的 32 位二进制数s 并用 0
“填充”最后 9 位.这是第二行出现的地方:
You can ignore the
bits == 32
check since it is not that relevant and probably is there just as a optimization.
//final int mask = (bits == 32) ? 0 : 0xFFFFFFFF - ((1 << bits)-1);
final int mask = 0xFFFFFFFF - ((1 << 9)-1);
0xFFFFFFFF
将为您提供所有 1
的 32 位二进制数秒。 1
左移 9 位 ( 1 << bits
) 会给你 512 和 512 - 1
二进制是111111111
:
1 << 9 10 00000000
- 1 1
--------------------------------------------------
1 11111111
当您减去这些值时,您将得到二进制的子网掩码:
0xFFFFFFFF = 11111111 11111111 11111111 11111111
- (1 << 9)-1 = 1 11111111
--------------------------------------------------
11111111 11111111 11111110 00000000
这正是我们想要的网络掩码。
注意:这可能不是计算二进制值的最直观方法。我喜欢从全 1 的二进制数开始,并且 signed int 中的数字的十进制值为 -1
.然后我只是将它向左移动主机位的数量,就是这样。 (此外,如果您要处理大于 32 位的整数,您可以使用 0xFFFFFFFF 对其进行屏蔽):
(-1 << 9) & 0xFFFFFFFF
其余代码将二进制值转换为点分十进制表示形式 — 255.255.254.0。
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
返回语句由几个串联的字符串组成,以 IP 地址开头,然后是每个八位字节的十进制表示形式。二进制掩码右移 (4-n)*8
位(其中 n
是八位字节数)并使用二进制 AND 和 0xFF 你只得到最后 8 位,然后由 Integer.toString
解析.
结果是172.16.0.1/255.255.254.0
.
关于java - 从 CIDR 表示法到 IP 地址/子网掩码(点十进制)的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23385765/
我有一个 VPC,假设它的 CIDR block 是 10.0.0.0/16。我在那个 VPC 中有几个随机子网。他们的 CIDR 可能类似于 10.0.128.0/19、10.0.32.0/19、1
当我们使用kubeadm设置k8s集群时,有两个选项需要配置: --pod-network-cidr --service-cidr(默认“10.96.0.0/12”) 问题是: 如果我将 10.244
我有 2 个数据框。 One(df1) 具有 CIDR 和一列,该列始终为 1 以丰富第二个数据帧。另一个数据帧(df2)有一个 ip 列表。我想可能通过 df1 中的 CIDR 迭代 IP,并标记
我有一个包含两个 cidr 数组的表。一个包含主机 ip 地址,第二个包含网络地址。 我需要编写一个函数来执行这样的查询: SELECT * from sometable WHERE ip_addr
我在 AWS 上创建了一个 VPC(公共(public)子网和私有(private)子网),IPV4 CIDR block 为 10.0.0.0/26 (即它可以有 2^6 = 64 个 IP 地址以
我正在努力在AWS上创建一个子网。这是我一直纠结的问题:创建一个新子网。将其添加到与第一个子网相同的vPC中,并使用相邻的CIDR块。您使用了什么CIDR块?。但是,我最初的VPC使用的是10.0.1
想知道这是怎么重叠的,好像是后来才出现的。 CIDR block 10.0.96.32/18 overlaps with pre-existing CIDR block 10.0.96.0/28 fr
我有一个问题问以下问题: Suppose a router has the following CIDR entries in its routing table: Net/Prefix Next Ho
我正在编写一个程序,我需要遍历从给定 cidr 的用户派生的地址列表(例如 75.24.64.0/24 )。 我看了一些code ,但这似乎过于复杂。 最后我决定使用一个看起来像这样的结构: stru
我了解 CIDR 的一般概念以及前缀和后缀位的工作原理,并且我大致了解您可以取一个地址说: 73.132.68.12/24 有 24 个前缀和 8 个后缀位。与此对应的网络地址将是: 73.132.6
为了获得对应于 IP 地址/网络掩码的值“24”,我有这段工作代码: - set_fact: ip: "{{ ansible_default_ipv4.address }}/{{ansible
我读到 10.240.0.0/24 最多可以托管 254 个 IP 地址。怎么样? 我如何直观地理解 /24 在这里做什么来帮助提供 254 个唯一的 ip 地址? 最佳答案 TL;博士; 计算主机数
我想制作一个 CIDR 范围列表,代表我指定的 CIDR 范围之外的地址。 作为一个简化的例子: 如果我的 IP 范围从 8.8.8.8 到 8.8.8.10,我将能够用 CIDR 范围 8.8.8.
给定一个网络定义,如 192.168.1.0/24 ,我想转换 /24 CIDR 到四位网络掩码,在本例中 255.255.255.0 . 不应使用额外的 gem 。 最佳答案 这里的实际方法非常简单
例子: 我有这个网络掩码:255.255.255.0 在 bash 中,是否有一个命令或一个简单的脚本来将我的网络掩码转换为符号 /24? 最佳答案 函数使用 subnetcalc : IPprefi
例如,有人可以准确解释 CIDR 块的工作原理以及它如何转换为 0.0.0.0/32 吗?请使用外行的术语,或者甚至是与网络无关的类比。似乎找不到适合我的解释。谢谢!! 最佳答案 无类别域间路由 (C
我有一个 Azure 问题。我在 Azure 云服务中使用 terraform。我尝试在那里启动 2 个 AKS 集群。但我总是收到一个错误,说我的 CIDR 设置错误。 我在集群一中使用: reso
我有以下内容:- 开始范围=“10.40.0.0/16” end_range =“10.100.0.0/16” 我必须编写一个逻辑来迭代从start到end的所有可能范围(具有相同的子网掩码/16)。
我正在寻找一种使用内置 cidr 类型从存储在 postgresql 中的 cidr block 获取直接子网络的方法。 示例数据库 CREATE TABLE nets ( id serial
我有一个 Net 表,其中是网络列表 -- 表:净值 CREATE TABLE net ( id serial NOT NULL, cidr cidr, description text,
我是一名优秀的程序员,十分优秀!