生成随机IP地址

22

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

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();

}

我想要随机为ipAddress赋值,形式为p1,p2,p3,并且最后一位应该是0


Java没有所谓的输出参数。 - The Nail
那是什么意思?我无法理解。 - AKIWEB
哦,不用在意;我以为你想要给p1/p2/p3分配一些东西,但是我回复得有点太快了。仍然不确定在调用generateIPAddress之后修改(p3 += inc;等)应该做什么。我应该说:Java没有方法级别的静态变量,因为离开方法作用域后,对p1/p2/p3的修改将会丢失。 - The Nail
这个链接可能会对你有所帮助:http://www.texamples.com/how-to-generate-random-passwords-in-java/。 - brainless
9个回答

56
Random r = new Random();
return r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256);

4
这会生成一系列可疑的地址,如0.0.0.0和255.255.255.255等私有IP地址范围和多播地址。 - joev
1
255.255.255.255 是通用广播地址。使用时请谨慎! - 0xBAADF00D

14

使用Google Guava

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

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


这个答案和被接受的答案有相同的缺陷,可能会生成像 0.0.0.0255.255.255.255 这样的 IP 地址。 - KARASZI István
这个库支持基于给定子网生成随机IPv6 IP地址吗? - Arya

4

我最近开发了一个小型库mockneat,可以使用不同类型的约束生成随机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? - Mario Trucco
不,它已经包含在内了。 - Andrei Ciobanu
哦,谢谢。所以我似乎无法确保获取非私有地址。 - Mario Trucco
1
是的。观察得很好。你能在项目的Github上添加这个问题吗?我会在未来的版本中实现它。 - Andrei Ciobanu
经典网络已于1993年被弃用。 - Martin Schröder

0

使用以下代码生成带有子网掩码的随机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);
    }
}

0

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

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

真正的问题是将这些值转换为地址的代码会将它们进行移位。将p1左移24位,p2左移16位,p3左移8位。理解调用方法中应用的限制,您可以知道p1p2p3永远不会超过255,因此在这种情况下,如果知道移位8或更多位会导致结果为0,则地址的每个元素都不会产生除0以外的值,最后一个八位组始终为0,因此生成的地址将是0.0.0.0

如果你想防止它成为0.0.0.0,第一件事是移除位移操作。这仍然会保持最后一个字段为0,因为它从未被设置过,但应该会产生地址。

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


0
当您调用generateIPAddress(p1, p2, p3)时,p1255p2p30
这行
int b1 = (p1 >> 24) & 0xff;

p1 向右移动 24 位。在移位之前,p1 的值为 11111111。移位后的结果为 0。实际上,您也可以使用

int b1 = p1 >> 8;

由于p1只有其8个最低有效位被打开。使用& 0xff是多余的,因为操作是在两个int操作数之间进行的。所以b10

p2p3的值都为0,因此移位(无论是16还是8)不会改变它的任何一位,导致b2b3也都是0

b4明确设置为0

因此,所有的b1b2b3b4都是0,从中创建ip1ip4。因此,方法generateIPAddress(p1, p2, p3)始终返回0.0.0.0

然后p3 += inc;5加到0。结果p3现在是5
条件if (p3> 255)将始终失败,因为p35,小于255...

0

我写了一段简短的代码来过滤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);

0

这个函数将帮助您生成无限数量的随机 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进制输出中的第一位数字,您就会无缘无故地限制可能值的输出空间。 - Patrick Mevzek

0
生成随机 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;
     }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接