Shuffle Netpbm Pixels Reproducibly with pamshuffle
pamshuffle scrambles the pixels in a Netpbm image on demand, which is handy for anonymising test data or generating noise from a clean source. You will finish with a repeatable way to rearrange pixels, 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, and 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 never moves 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, which is different from rotating or flipping the whole image. A source made entirely from horizontal stripes stays 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, so two runs are 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
Recovery
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.
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
- Still looks striped? The default mode does not cross row boundaries. Use
-columnfor one shared column permutation, or thepamflippipeline for a complete scramble. - Result not repeating? Check that every shuffle stage in the pipeline has an explicit seed.
- Multi-image stream in, multi-image stream out. pamshuffle processes each image in a stream independently and does not combine them into one larger image, so preserve the stream if later tools expect that structure.
Done means
- pamshuffle and its Netpbm version were checked locally.
- Input untouched: output was written to a separate destination.
- Shuffle mode chosen deliberately: independent row shuffles or the shared
-columnpermutation. - Every reproducible run records an integer seed and is verified with
cmp. - Complete scramble uses
pamfliparound a seeded shuffle and is promoted only after a non-empty output check. - No system configuration changed and no root access required.