Shuffle Netpbm Pixels Reproducibly with pamshuffle
You will finish with a repeatable way to rearrange the pixels in a Netpbm image, choose between independent row shuffles and a shared column shuffle, and build a complete scramble when you need one. The examples use Netpbm 11.5.2, installed here as package version 2:11.05.02-1.1build1.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, the netpbm package, and an image in a format that Netpbm can read. The command does not edit its input: it reads an image and writes the result to standard output. No elevated privileges are normally needed.
1. Check the installed command
Confirm the executable and package before building a pipeline. This is a read-only check:
$ command -v pamshuffle
/usr/bin/pamshuffle
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
The local manual describes pamshuffle as a pixel-location operation. It moves existing pixels, but does not add or discard them. It accepts one optional input file; without that argument it reads standard input. Its output always goes to standard output, so direct output to a new file while testing.
Checkpoint
Identify the input image and choose a new destination. Shell redirection with > truncates an existing file before the program starts, so do not point it at the only copy of a useful image.
2. Shuffle each row independently
With no options, pixels change position within their own rows. This preserves each row's pixels as a set and does not move a pixel to another row. For an existing image, use a fresh output name:
$ pamshuffle /path/to/input.ppm > shuffled.ppm
$ file shuffled.ppm
The exact wording from file varies by format, but a successful run should leave a non-empty Netpbm image at the destination. If you want a format-neutral test image, generate a one-row PAM image with pamseq and feed it through the same standard-output pipeline:
$ pamseq 1 15 | pamshuffle > shuffled.pam
$ file shuffled.pam
shuffled.pam: Netpbm PAM image file, size = 16 x 1
For a multi-row image, this default mode performs a separate random permutation for each row. That is different from rotating or flipping the whole image. A source made entirely from horizontal stripes remains visually unchanged because no pixel crosses a row boundary.
3. Make a result reproducible
By default, the seed comes from the time of day and process ID. Two runs are therefore expected to produce different arrangements. Supply an integer to make the pseudo-random sequence repeat:
$ pamshuffle -randomseed=20260925 /path/to/input.ppm > shuffled-a.ppm
$ pamshuffle -randomseed=20260925 /path/to/input.ppm > shuffled-b.ppm
$ cmp --silent shuffled-a.ppm shuffled-b.ppm
$ printf 'same seed: identical output\n'
same seed: identical output
The option can also use whitespace instead of the equals sign:
$ pamshuffle -randomseed 20260925 /path/to/input.ppm > shuffled.ppm
Use a recorded seed in a build, test fixture or reproducible image pipeline. The seed repeats the command's random choices for the same input and installed implementation; it is not encryption and must not be treated as a secret. If you omit it, keep the output as an intentionally variable result.
Checkpoint
Rerun the two commands with the same input and seed, then compare the complete files with cmp. A non-zero cmp result means the files differ; it is not itself an error when you deliberately changed the seed.
4. Shuffle columns instead
Use -column when the same horizontal movement should be applied to every row:
$ pamshuffle -column -randomseed=20260925 /path/to/input.ppm > shuffled-columns.ppm
This mode treats vertical columns as the units being moved. Every row receives the same column permutation, so vertical relationships are retained. The option is useful when rows represent aligned samples and independent row permutations would destroy that alignment.
Do not confuse the option name with a vertical flip. -column changes which columns occupy each position; it does not reverse the image and it does not rearrange rows. Long options may use two hyphens, so --column is accepted as well. Spell options in full in scripts even though the manual permits unique abbreviations.
5. Build a complete scramble
pamshuffle never rearranges rows by itself. The manual's complete-scramble pattern first turns rows into columns with pamflip, shuffles those units, turns the image back, then performs a normal row shuffle:
$ pamflip -cw /path/to/input.ppm \
| pamshuffle -randomseed=20260925 \
| pamflip -ccw \
| pamshuffle -randomseed=20260925 \
> complete-scramble.ppm
Keep the two seed values explicit when you need a repeatable pipeline. This command writes only the final stream to the destination. If an earlier stage fails, the shell pipeline can still leave a partial output unless you use a shell with pipeline-status checking and a temporary destination. For a safer replacement, write to a new file, inspect it, then rename it:
$ pamflip -cw /path/to/input.ppm | pamshuffle -randomseed=20260925 | pamflip -ccw | pamshuffle -randomseed=20260925 > complete-scramble.ppm.new
$ test -s complete-scramble.ppm.new
$ mv complete-scramble.ppm.new complete-scramble.ppm
If the pipeline fails, retain the original and remove only the incomplete complete-scramble.ppm.new after checking why it failed. The mv command is the state-changing step. Do not use sudo unless your chosen input or output directory is deliberately protected, and do not overwrite the source.
6. Diagnose the common traps
An empty output is usually a redirection or pipeline problem, not a request for elevated access. Check the source path and readability first:
$ test -r /path/to/input.ppm && echo readable
$ ls -lh /path/to/input.ppm
If you expected every pixel to move but the picture still looks striped, remember that the default mode does not cross row boundaries. Use -column for one shared column permutation, or the pamflip pipeline for a complete scramble. If the output must be repeatable, check that every shuffle stage has an explicit seed.
The program supports a multi-image stream and processes each image independently. That means a stream containing several images remains a stream containing several images; it does not combine them into one larger image. Preserve the stream if later Netpbm tools expect that structure.
Done means
pamshuffleand its Netpbm version were checked locally.- The input remains untouched and output was written to a separate destination.
- You chose independent row shuffles or the shared
-columnpermutation deliberately. - Every reproducible run records an integer seed and verifies it with
cmp. - A complete scramble uses
pamfliparound a seeded shuffle and is promoted only after a non-empty output check. - No command changed system configuration or required root access.