【问题标题】:Generate Random IP Address生成随机 IP 地址
【发布时间】:2012-03-03 10:03:33
【问题描述】:

我想生成一些随机 IP 地址。但是这个 generateIPAddress 函数每次都会返回 0.0.0.0 字符串作为 ipAddress。但它应该每次都返回 0.0.0.0 以外的一些随机 ipAddress。有什么建议为什么会发生?

private void callingGeoService() {
    int p1 = 255;
    int p2 = 0;
    int p3 = 0;
    int inc = 5;

    String ipAddress = generateIPAddress(p1, p2, p3);

    p3 += inc;
    if (p3 > 255) {
        p3 = 0;
        p2 += inc;
        if (p2 > 255) {
            p2 = 0;
            p1--;
            if (p1 <= 0) {
                p1 = 0;
            }
        }
    }
}

这是 generateIPAddress 方法

private String generateIPAddress(int p1, int p2, int p3) {

    StringBuilder sb = null;

    int b1 = (p1 >> 24) & 0xff;
    int b2 = (p2 >> 16) & 0xff;
    int b3 = (p3 >>  8) & 0xff;
    int b4 = 0;

    String ip1 = Integer.toString(b1);
    String ip2 = Integer.toString(b2);
    String ip3 = Integer.toString(b3);
    String ip4 = Integer.toString(b4);

    //Now the IP is b1.b2.b3.b4
    sb = new StringBuilder();
    sb.append(ip1).append(".").append(ip2).append(".").append(ip3).append(".").append(ip4);
    // System.out.println(sb);

    return sb.toString();

}

我想以p1,p2,p3 的形式为ipAddress 分配一个随机值,最后一位应该是0

【问题讨论】:

  • Java没有out-parameters这样的东西
  • 这是什么意思。我没听懂?
  • 哦,没关系;我以为你想为 p1/p2/p3 分配一些东西,但我的反应有点太快了。仍然不确定调用generateIPAddress 后应该做什么修改(p3 += inc; 等)。应该说:Java没有方法级别的静态变量,因为离开方法作用域后p1/p2/p3的修改会丢失。
  • texamples.com/how-to-generate-random-passwords-in-java 这可能会对您有所帮助。

标签: java ip subnet


【解决方案1】:
Random r = new Random();
return r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256);

【讨论】:

  • 这会产生一大堆有问题的地址;诸如 0.0.0.0 和 255.255.255.255 之类的东西,以及私有 IP 地址范围和多播地址。
  • 255.255.255.255 是通用广播地址。谨慎使用这个!
【解决方案2】:

使用Google Guava

import com.google.common.net.InetAddresses;
...
String ipString = InetAddresses.fromInteger(random.nextInt()).getHostAddress();

当然,您可以验证生成的地址不是多播等。

【讨论】:

  • 这个答案与接受的答案有相同的缺陷,可能会生成像0.0.0.0255.255.255.255这样的IP地址。
  • 这个库是否支持基于给定子网生成随机 IPv6 IP?
【解决方案3】:

我最近开发了一个small library,它可以使用不同的类型约束生成随机的 IPv4 地址:

MockNeat mock = MockNeat.threadLocal();

String ipv4 = mock.ipv4s().val();
System.out.println(ipv4);

String ipClassA = mock.ipv4s().type(CLASS_A).val();
System.out.println(ipClassA);

String classAorB = mock.ipv4s().types(CLASS_A, CLASS_B).val();
System.out.println(classAorB);

List<String> ip4s = mock.ipv4s().list(10).val();
System.out.println(ip4s);

输出:

192.112.222.183
120.178.110.193
143.68.176.47
[112.246.76.178, 29.201.72.151, 67.105.2.128, 102.189.109.206, 157.146.176.212, 59.220.145.35, 47.171.185.233, 162.245.163.124, 19.203.21.194, 114.177.238.50]

【讨论】:

  • 我试过了,很好! CLASS_A 是否排除 CLASS_A_PRIVATE?
  • 不,它没有。它包括在内。
  • 哦,谢谢。所以我似乎无法确保获得一个非私人地址
  • 是的。良好的观察力。您能否将此作为问题添加到项目的 github 上。我将在未来的版本中实现它。
  • 有类网络已在 1993 中被弃用。
【解决方案4】:

要生成带有Subnet Mask 的随机IP 地址,请使用以下代码(请注意,此代码中的子网掩码具有CIDR 格式):

import java.util.Random;
import java.util.Scanner;

public class mainClas {

    public static int findRange(int mask)
    {
        int x = 8 - mask;
        int sum = 0;
        for (int i = 0 ; i < x ; i++) {
            sum += Math.pow(2 , i);
        }
        return sum;
    }

    public static int findFixedPart(String IPPrefix, int i)
    {
        String f = IPPrefix.split("\\.")[i];
        return Integer.valueOf(f);
    }

    public static String generateRandomIP(String IPPrefix, Integer mask)
    {
        String IP="";
        Random r = new Random();
        if (mask < 8)
            IP = (findFixedPart(IPPrefix, 0) + r.nextInt(findRange(mask))) + "." + r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256);
        else if (mask >7 && mask < 16)
            IP = findFixedPart(IPPrefix, 0) + "." + (findFixedPart(IPPrefix, 1) + r.nextInt(findRange(mask-8))) + "." + r.nextInt(256) + "." + r.nextInt(256);
        else if (mask >15 && mask < 24)
            IP = findFixedPart(IPPrefix, 0) + "." + findFixedPart(IPPrefix, 1)  + "." + (findFixedPart(IPPrefix, 2) + r.nextInt(findRange(mask-16))) + "." + r.nextInt(256);
        else if (mask >23 && mask < 33)
            IP = findFixedPart(IPPrefix, 0) + "." + findFixedPart(IPPrefix, 1)  + "." + findFixedPart(IPPrefix, 2) + "." + (findFixedPart(IPPrefix, 3) + r.nextInt(findRange(mask-24)));
        return IP;
    }

    public static void main(String[] inpout)
    {

        System.out.println("Enter IP Prefix: ");
        Scanner sc = new Scanner(System.in);
        String IPPrefix = sc.nextLine();
        System.out.println("Enter Mask: ");
        Integer mask = sc.nextInt();

        // Find random IP in Subnet mask
        String IP = generateRandomIP(IPPrefix, mask);
        System.out.println(IP);
    }
}

【讨论】:

    【解决方案5】:

    假设您实际上并不关心生成的 IP 地址是否以任何形式有效,那么您有一个简单的问题。

    用于生成地址的代码将参数p3p2 设置为小于255 的值。 p1 被困在 2550 之间。

    真正的问题是,将其转换为地址的代码会移动这些值。 p124p216p38。了解调用方法中的限制,可以知道p1p2p3永远不会超过255,所以在这种情况下知道8或更多的移位将导致@987654338 @,地址的任何单个元素都不会产生除0以外的值,最后一个八位字节将始终为0,因此结果地址将为0.0.0.0

    如果要防止它成为0.0.0.0,首先要做的就是删除移位操作。这仍将最后一个字段保留为0,因为它从未设置过,但它应该产生地址。

    同样,这并不关心地址的状态,使用此方法您最终会得到广播、多播和仅限本地地址。

    【讨论】:

      【解决方案6】:

      当您调用 generateIPAddress(p1, p2, p3) 时,p1255p2p30

      这一行

      int b1 = (p1 >> 24) & 0xff;
      

      p1 向右移动 24 位。在班次之前p111111111。移位结果为0。其实你也可以用

      int b1 = p1 >> 8;
      

      因为p1 只打开了它的 8 个最低有效位。 &amp; 0xff 的使用是多余的,因为操作在两个 int 操作数之间。所以b10

      p2p3 使用值 0 传递,因此移位(168)不会改变它一点,导致 b2b3 被还有0

      b4 明确设置为0

      所以所有b1b2b3b4 都是0,您可以从中创建ip1ip4。所以generateIPAddress(p1, p2, p3)方法总是返回0.0.0.0

      然后p3 += inc;5 添加到0p3 中的结果现在是 5

      条件if (p3 &gt; 255) 将始终失败,因为p35,即&lt; 255...

      【讨论】:

        【解决方案7】:

        此功能将帮助您生成无限数量的随机 IP 地址:

                StringBuilder ip = new StringBuilder("xx.xx.xx.xx");
                    for (int i=0 ; i <11;i++){
        
                        if (i==2){}
                        else if (i==5){}
                        else if (i==8){}
                        else{
                            Random r = new Random();
                            int random = r.nextInt((9 - 1) + 1) + 1;
                            char c = (char)(random+'0');
                            ip.setCharAt(i, c);
                        }
        
                    }
        
                    Log.v("ip","Server IP : "+ip);
        

        如您所见,我生成 xx.xx.xx.xx ip 格式,您可以处理它以生成任何 ip 格式。

        【讨论】:

        • 一个 IPv4 地址不是“xx.xx.xx.xx”,它是 4 个 8 位整数,或者如果您愿意,也可以是一个 32 位整数。通过避免基于 10 的输出中的第一个数字,您只是限制了可能值的传出空间,没有任何理由。
        【解决方案8】:

        我写了一个简短的代码来过滤掉wikipedia 中列出的特殊范围(略多于仅基于第一个八位字节):

        Random r = new Random();
        Integer prefix;
        while ({
            prefix = r.nextInt(256);
            prefix in [0,10,100,127,172,192,198,203,224,240,255]
        }());   
        return prefix + "." + r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256);
        

        【讨论】:

          【解决方案9】:

          一种非常简单快速的生成随机ip地址的方法:

          import java.util.Random;
          
          public class IpAddressHelper {
          
               public static String createRandom() {
                   return randomNumber() + "." + randomNumber() + "." + randomNumber() + "." + randomNumber();
               }
          
               public static int randomNumber() {
                   return new Random().nextInt((255 - 1) + 1) + 1;
               }
          }
          

          【讨论】:

            猜你喜欢
            • 2017-10-02
            • 2012-05-03
            • 2014-01-27
            • 2019-05-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-10-26
            相关资源
            最近更新 更多