确定 IP 地址的网络和主机 ID 部分
Posted
技术标签:
【中文标题】确定 IP 地址的网络和主机 ID 部分【英文标题】:Determine the network and host ID portion of an IP address 【发布时间】:2012-01-28 21:22:42 【问题描述】:我需要制定有关如何计算 IP 地址的网络和主机部分的算法。
主机 ID 是公共部分吗?网络 ID 是用于在本地网络中定位计算机的私有部分吗?
如果子网掩码的值小于 255,则必须将 IP 地址中的相应八位字节分解为二进制,以确定数字的哪一部分是主机 ID,哪一部分是网络 ID。结果二进制数总是一分为二吗?
(例如,IP地址192.168.33.22,子网掩码为255.255.224.0意味着八位位组33被分解如下:0010|0001表示0010是网络ID部分,0001是主机ID部分?)
提前感谢您的帮助。
【问题讨论】:
【参考方案1】:主机 ID 是公共部分吗?网络 ID 是用于在本地网络中定位计算机的私有部分吗?
IP 地址的主机和网络部分与公共和私有无关。
如果子网掩码的值小于 255,则必须将 IP 地址中的相应八位字节分解为二进制,以确定数字的哪一部分是主机 ID,哪一部分是网络 ID。结果二进制数总是一分为二吗? ...子网掩码 255.255.224.0 意味着持有 33 的八位字节被分解如下:0010|0001...
你的例子是错误的。具体来说,当您将 33 个八位字节吐为 0010|0001
(其中 | 是网络和主机之间的分隔符)时,您假设 224 中有四个连续的二进制位...
子网掩码中包含 224 的八位字节中包含三个连续的二进制 1:11100000
。因此,整个 IP 地址的“网络部分”为:192.168.32.0
。 IP 地址的“主机部分”是0.0.1.22
。使用您的表示法,ip 192.168.33.22(掩码 255.255.224.0)的第三个八位字节是:001|00001
。
要获取 IP 地址的网络部分,您必须对 IP 地址及其网络掩码执行二进制 AND
。主机部分是反向网络掩码的二进制AND
(位在 0 和 1 之间翻转)。
编辑
让我们再举一个例子来解决您的评论:
IP 地址 192.168.255.22,网络掩码 255.255.224.0
此地址的网络部分是 192.168.224.0,地址的主机部分是 0.0.31.22。我故意选择示例中的数字以使数学尽可能明显。请将 224 和 31 转换为二进制,它应该清楚。如果没有,请参考wikipedia article on subnetting
【讨论】:
嗨,迈克,我不确定我是否遵循关于网络和主机 ID 部分的最后部分。你是说因为224的二进制版本是11100000,所以网络部分就是三个1对应的部分?并且主机 ID 部分是与 0 相关联的部分?再次感谢您的解释。 是的,这回答了我的问题。似乎该算法使用了子网掩码中二进制文件的 1s 部分。这意味着在我的示例中,第三个八位字节为 31 的相同 IP 地址的主机 ID 为 0.0.31.22。如果我在这里错了,请纠正我。 @fwc,你错了。阅读我在回答中所说的关于 192.168.33.22 和掩码 255.255.224.0 @MikePennington- 我会计算如下:第三个八位组的子网掩码仍然是 11100000,所以 33 的二进制是 00011111;因此它将拆分如下 000|11111 其中行是网络和主机 ID 之间的分隔线,还是我还遗漏了什么? @fwc,请在 python 解释器中检查您的二进制数学。>>> int('00011111', 2)
。结果是 31,而不是 33【参考方案2】:
您可以使用以下脚本:
#!/bin/sh
GetNumericIP()
ipbin=0
for part in `echo $1 | awk -F'.' 'print $1 " " $2 " " $3 " " $4'`
do
ipbin=`expr $ipbin \* 256`
ipbin=`expr $ipbin + $part`
done
echo "$ipbin"
GetSrtingIP()
ipbin=$1
count=0
while [ $count -le 3 ]
do
rem=`expr $ipbin % 256`
ipbin=`expr $ipbin / 256`
if [ -z "$ipstr" ]
then
ipstr=$rem
else
ipstr=`echo $rem.$ipstr`
fi
count=`expr $count + 1`
done
echo $ipstr
mask=$2
maskbin=`GetNumericIP $mask`
ip=$1
ipbin=`GetNumericIP $ip`
networkid=$(( $maskbin & $ipbin ))
networkid=`GetSrtingIP $networkid`
echo "networkid = $networkid"
【讨论】:
【参考方案3】:你把事情复杂化了。
IPv4 地址(和子网掩码)只是显示在dot-decimal notation 中,只是为了让它们对人类更具可读性。在计算机中,它们只是 4 字节的连续内存(通常存储在例如long int
中):
掩码中的1
s 表示标识网络号的位,因此只需使用bitwise AND operation 即可提取网络号:
自从引入CIDR(在此之前地址的class表示网络/主机边界),主机通常只知道自己自己网络的掩码,因此无法将任意地址(例如datagram 的目标地址)划分为网络号和主机号。
那有什么意义呢?好吧,源主机仍然可以对目标地址和其(源的)自己的网络掩码进行按位与运算。虽然该操作的结果不一定会产生有意义的网络号,但当且仅当它们在同一网络上时,它才会匹配源的网络号:
1234563发往该 MAC);如果它们不同,源必须将数据报发送到位于其自己网络上的router(使用上述过程到达该路由器);路由器将看到该帧是发给它的,但数据报不是,然后应该将数据报(封装在不同的帧中)转发到目的地。许多主机只知道一个路由器,他们的“default gateway”,尽管其他配置也是可能的。
那些不能识别源网络号的地址位,显然在其网络掩码中由0
s 表示,可以被认为是它的主机号——尽管在同一地址中提取它实际上既无意义也无用如上所述的方式:即使在与自己网络上的主机通信时,它的完整地址也用于标识,而不是单独使用主机号。
也就是说,作为一个纯粹的学术练习,当然可以使用掩码的complement 执行按位与:
地址 11000000 10101000 00100001 00010110 192.168.33.22 ~掩码 00000000 00000000 00011111 11111111 0.0.31.255 (和) - - - - - - - - - - - - - - - - - - - - - - - - - 主机 00000000 00000000 00000001 00010110 0.0.1.22所以,为了解决您的问题:
主机 ID 是公共部分吗?网络 ID 是用于在本地网络中定位计算机的私有部分吗?
整个地址是“公开的”;没有“私人”部分。诸如 ARP(使用完整地址)之类的查找协议用于定位本地网络中的计算机。
如果子网掩码的值小于 255,则必须将 IP 地址中的相应八位字节分解为二进制,以确定数字的哪一部分是主机 ID,哪一部分是网络 ID。结果二进制数总是一分为二吗?
没有什么是“一分为二”的。之所以出现这种情况,是因为点十进制表示法旨在使 IPv4 地址对人类更具可读性(尽管该决定是在 CIDR 发明之前做出的,当时网络编号始终与字节边界对齐,因此从未导致明显的“分裂"的十进制数)。
【讨论】:
【参考方案4】:Host address portion and network address portion can be easily identified.
Use this trick.
Class A: N.H.H.H
Class B: N.N.H.H
Class C: N.N.N.H
(N= network H=Host)
Class A network range: 1-127
Class B network range: 128-191
Class C network range: 192-223
参考:https://www.youtube.com/watch?v=ddodZeXUS0w
【讨论】:
有类寻址在 1993 年被 CIDR 取代。以上是关于确定 IP 地址的网络和主机 ID 部分的主要内容,如果未能解决你的问题,请参考以下文章