确定 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 中):

存入电脑:11000000 10101000 00100001 00010110 为人类显示:192. 168. 33. 22 存入电脑:11111111 11111111 11100000 00000000 为人类显示:255. 255. 224. 0

掩码中的1s 表示标识网络号的位,因此只需使用bitwise AND operation 即可提取网络号:

地址 11000000 10101000 00100001 00010110 192.168.33.22 掩码 11111111 11111111 11100000 00000000 255.255.224.0 (和) - - - - - - - - - - - - - - - - - - - - - - - - - 网络 11000000 10101000 00100000 00000000 192.168.32.0

自从引入CIDR(在此之前地址的class表示网络/主机边界),主机通常只知道自己自己网络的掩码,因此无法将任意地址(例如datagram 的目标地址)划分为网络号和主机号。

那有什么意义呢?好吧,源主机仍然可以对目标地址和(源的)自己的网络掩码进行按位与运算。虽然该操作的结果不一定会产生有意义的网络号,但当且仅当它们在同一网络上时,它才会匹配源的网络号:

1234563发往该 MAC);

如果它们不同,源必须将数据报发送到位于其自己网络上的router(使用上述过程到达该路由器);路由器将看到该帧是发给它的,但数据报不是,然后应该将数据报(封装在不同的帧中)转发到目的地。许多主机只知道一个路由器,他们的“default gateway”,尽管其他配置也是可能的。

那些不能识别源网络号的地址位,显然在其网络掩码中由0s 表示,可以被认为是它的主机号——尽管在同一地址中提取它实际上既无意义也无用如上所述的方式:即使在与自己网络上的主机通信时,它的完整地址也用于标识,而不是单独使用主机号。

也就是说,作为一个纯粹的学术练习,当然可以使用掩码的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 部分的主要内容,如果未能解决你的问题,请参考以下文章

对于IP地址,怎样区分主机ID和网络ID

7.10 IP地址的格式 以及 网段地址等

IP地址与子网掩码

TCP/IP--子网和CIDR

ip通信基础(第四周上)

子网掩码通常是多少?