Search code examples
javauniquesequencesteganography

How to generate a unique sequence of numbers?


Well, I'm working with steganography and looking for a way to get different pixels in an image with no random values through a keyword, so I wonder if there is any way or algorithm that creates a sequence of unique numbers through a key.

PS: Through the same keyword I need to retrieve the list to find out which pixels have been modified, and i'm using java.


Solution

    • Create an iterable that can be shuffled, like a list.
    • Define each element to be a pixel coordinate, such as (0, 0), (0, 1), (0, 2), etc.
    • Initialise your random number generator with a specific seed .
    • Shuffle the list.

    What will come out will be a list of the pixel coordinates in a randomised order. By iterating though its members sequentially, you'll transverse your pixels in that randomised order without visiting the same one twice. Since you initialise the PRNG with the same seed each time, the randomised order is guaranteed to be the same.

    Example

    Assume you have a 2x3 image. A list of its pixels would look like this.

    [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2]]
    

    After shuffling it with a specific seed, it could look like this.

    [[1, 2], [0, 2], [1, 1], [0, 1], [1, 0], [0, 0]]
    

    So if you wanted to modify 3 pixels, those would be [1, 2], [0, 2] and [1, 1].

    Code

    Conceptually speaking, you can do this with a list of lists just as described above. However, performance wise it is a better to shuffle a list of integers from 0 to n-1, where n is the number of pixels. You can convert these numbers into pixel coordinates with one division and one modulo operation. You can easily extend this to 3 dimensions if you want to include colour planes.

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Random;
    
    class ShufflePixels {
        private static List<Integer> shuffleIntegers(int n, long seed) {
            List<Integer> list = new ArrayList<Integer>();
            for (int i = 0; i < n; i++) {
                list.add(i);
            }
            Collections.shuffle(list, new Random(seed));
            return list;
        }
    
        public static void main(String[] args) {
            int height = 2;
            int width = 3;
            long seed = 34758L;
    
            List<Integer> pixelOrder = shuffleIntegers(height * width, seed);
    
            for (int pixel : pixelOrder) {
                int x = pixel / width;
                int y = pixel % width;
                System.out.println(x + " " + y);
            }
        }
    }