Question

I wanted to scramble a String, to make it unreadable and so came up with this method:

public String scrambleWord(String start_word){

     char[] wordarray = start_word.toCharArray();

        char[] dummywordarray = start_word.toCharArray();

        Random random = new Random();

        int r = random.nextInt(wordarray.length-1);
        int i = 0;

        int j = r+1;

        while(i <= r){

            dummywordarray[wordarray.length -i-1] = wordarray[i];

            i++;
        }


        while (j <= wordarray.length -1){

            dummywordarray[j-r-1] = wordarray[j];

            j++;

        }

        String newword = String.valueOf(dummywa);



        return newword;

SO I first converted the string to a char array, and in my method I had to duplicate the char array "dummywordarray". Passing once through this algorithm every lette rof the word will have changed position. But it wont be scrambled very well, in the sense that you could put it back together at a glance. SO I passed a given String of less than 9 characters through the method 7 times, and the words are fairly well scrambled, i.e. unreadable. But I tried it with a 30 character string and it took 500 passes before I could guarantee it was nicely scrambled. 500! I'm sure there is a better algorithm, I'd like some advice on either a)improving this method or b)a better way.

Was it helpful?

Solution

How about

ArrayList<Character> chars = new ArrayList<Character>(word.length());
for ( char c : word.toCharArray() ) {
   chars.add(c);
}
Collections.shuffle(chars);
char[] shuffled = new char[chars.size()];
for ( int i = 0; i < shuffled.length; i++ ) {
   shuffled[i] = chars.get(i);
}
String shuffledWord = new String(shuffled);

In other words, you could take advantage of the existing java.util.Collections.shuffle(List) method. Unfortunately you have to jump through a couple of hoops to use it, since you can't use primitives in Generics.

Edit:

The basic way that shuffle works (see the Javadoc for the full explanation), is like this:

for position = last_index to first_index
   let swap_pos = random number between first_index and position, inclusive
   swap(swap_pos, position)

Edit 2:

This approach is significantly less verbose with Guava's Chars utilities:

List<Character> chars = Chars.asList(word.toCharArray());
Collections.shuffle(chars);
String shuffledWord = new String(Chars.toArray(chars));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top