Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java randomizing String

I'm trying to generate meaningless words without using any Random() functions. I figured out that i can use current clock or mouse coordinate. And i picked to use current clock. Here is the code i wrote.

private final char[] charray = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

private char getRandomCharacter(){
    return charray[random(charray.length)];
}

private int random(int value){
    value =(int) System.nanoTime()% 52;
    return value;
}

protected Randomizer(){
    boolean running = true;
    int count = 0;
    int max = 5;
    while(running){
        StringBuilder sb = new StringBuilder();
        int size = random(25) + random(25);
        for (int i = 0; i < size; i++) {
            sb.append(getRandomCharacter());
        }
        System.out.println("Random Line : " + sb.toString());

        if (count++ == max) {
            running = false;
            System.out.println("All of them are random.");
        }
    }
}

public static void main(String[] args) {
    new Randomizer();
}

I was expecting the out put like:

axdlMkjiIfjcmqQopv etc..

but i get something like this:

ZNNrrrUUUUxxxxbbbhhhLLLLoooRRRRRvvvYYYYBBBBfffI or JmmmPPKKKKnnnnRRBeeHHHHlllllOOOOrrrVVVVV

Why there are too much continuous. Is nanoTime too slow for that or what?I used currentTimeMillis before that and it was much worser. I couldn't figured out and couldn't find any source about how to random with current clock.

like image 999
Jarnsida Avatar asked Mar 09 '19 12:03

Jarnsida


People also ask

How do you randomize a string in Java?

Using randomUUID() java. util. UUID is another Java class that can be used to generate a random string. It offers a static randomUUID() method that returns a random alphanumeric string of 32 characters.

How do you create an alphanumeric string in Java?

Method 1: Using UUID util. UUID class can be used to get a random string. Its static randomUUID method acts as a random alphanumeric generator and returns a String of 32 characters. If you want a string of a fixed length or shorter than 32 characters, you can use substring method of java.

How do I randomly select a character from a string in Java?

To generate a random character from this string, we will use the length of setOfCharacters as the argument of random. nextInt() . Once a random integer is generated, we use it to get a character at a random index or position using charAt() .


3 Answers

You could get somewhat better results by defining charray as Character[] charray and make it a list: List<Character> chars = Arrays.asList(charray);
Use this list in getRandomCharacter() method:

 private char getRandomCharacter(){
     Collections.shuffle(chars); // shuffle before each use 
     return chars.get(random(chars.size()));
 }

And of course fix random:

private int random(int value){
    return (int) System.nanoTime()% value;
}

Output:

Random Line : tjnBUxTDeTulHfLqnEJBRBLXFqqikUYyrREzzwPwG
Random Line : MZpzJbOyCaqraRPsQPSK
Random Line : cEzKcsNHTmoVmT
Random Line : CmGXpDHGOsUufSxxStDVQruR
Random Line : XtFKmOAIisnXEdPikhAIcfzD
Random Line : GVxdnwgWLKZvQIGuofCIhiiUbKsEbmAyzVfNNPM

like image 172
c0der Avatar answered Oct 23 '22 03:10

c0der


You can use timing data (besides other data) to seed a random number generator, but only using timing data for randomness is not easy. It is possible, but can be very slow. See for example the code I wrote here on how to use other data to seed a secure random instance (H2 database, MathUtils.generateAlternativeSeed). It uses:

  • System.currentTimeMillis()
  • System.nanoTime()
  • new Object().hashCode()
  • Runtime.freeMemory(), maxMemory(), totalMemory()
  • System.getProperties().toString()
  • InetAddress
  • more timing data

This is to seed a secure pseudo-random number generator. This ensures you get enough entropy even on systems that don't have anything else running, don't know the current time, and have no UI.

But only relying on timing data, as you see yourself, is hard, as it depends on the operating system, time between method calls, the compiler, the hardware.

like image 44
Thomas Mueller Avatar answered Oct 23 '22 04:10

Thomas Mueller


Using only time is problematic as it limits the frequency you can ask for a random number and is also very implementation dependent.

A better approach would be to use the time as the seed and then use a pseudorandom generator, for example a linear congruential generator. You have more info in this answer. Take into account that this random number generator algorithm is not secure, and that as Thomas pointed out using only time as a seed might not be enough if you want a secure RNG in all systems.

So your code might look like this:

    private final char[] charray = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

private long seed;

private char getRandomCharacter() {
    return charray[random(charray.length)];
}

private int random(int value) {
    seed = (1103515245L * seed + 12345L) % 2147483648L;
    return (int)seed%value;
}

protected Randomizer() {
    boolean running = true;
    int count = 0;
    int max = 5;
    seed = System.nanoTime();
    while (running) {
        StringBuilder sb = new StringBuilder();
        int size = random(25) + random(25);
        for (int i = 0; i < size; i++) {
            sb.append(getRandomCharacter());
        }
        System.out.println("Random Line : " + sb.toString());

        if (count++ == max) {
            running = false;
            System.out.println("All of them are random.");
        }
    }
}

public static void main(String[] args) {
    new Randomizer();
}
like image 24
Sergio B Avatar answered Oct 23 '22 05:10

Sergio B