【问题标题】:Determine the network and host ID portion of an IP address确定 IP 地址的网络和主机 ID 部分
【发布时间】:2012-01-28 21:22:42
【问题描述】:

我需要制定有关如何计算 IP 地址的网络和主机部分的算法。

  1. 主机 ID 是公共部分吗?网络 ID 是用于在本地网络中定位计算机的私有部分吗?

  2. 如果子网掩码的值小于 255,则必须将 IP 地址中的相应八位字节分解为二进制,以确定数字的哪一部分是主机 ID,哪一部分是网络 ID。结果二进制数总是一分为二吗?

    (例如,IP地址192.168.33.22,子网掩码为255.255.224.0意味着八位位组33被分解如下:0010|0001表示0010是网络ID部分,0001是主机ID部分?)

提前感谢您的帮助。

【问题讨论】:

    标签: networking ip-address host subnet cidr


    【解决方案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

      所以,为了解决您的问题:

      1. 主机 ID 是公共部分吗?网络 ID 是用于在本地网络中定位计算机的私有部分吗?

        整个地址是“公开的”;没有“私人”部分。诸如 ARP(使用完整地址)之类的查找协议用于定位本地网络中的计算机。

      2. 如果子网掩码的值小于 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 取代。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-03
        • 2010-09-17
        • 2014-02-26
        • 2012-06-28
        • 2015-05-16
        相关资源
        最近更新 更多