For detection of file integrity, no error correction support, I recommend using
b2sum (part of coreutils, so if you have
sha256sum, you have
b2sum too), which calculates a 512-bit checksum using the
BLAKE2b hash function. On typical hardware it is faster than md5sum or sha1sum, and much (3×) faster than sha224sum/sha256sum etc.
For filesystem integrity checks and change detection, running "
ionice -c 3 nice -n 20 find root -type f -print0 | ionice -c 3 nice -n 20 b2sum -bz -" generates a list of paths and checksums that "
ionice -c 3 nice -n 20 b2sum -cz file" can check. Both commands run in the background, idle, and should not significantly slow down anything else running at the same time. Note that the list file uses NUL (
'\0') as the separator to support all possible file names, instead of newline, so you need to use e.g.
tr '\0' '\n' < file | less to view it.
For error correction, as mentioned by golden_labels, Parchive (PAR2 format) is what comes to my mind as closest existing common tool.
I've personally found that
fixing corruption using such a scheme is not worthwhile, compared to storing multiple copies in physically separate media. I do use checksums to
detect file corruption, but instead of trying to fix the corruption I distribute copies physically in the hopes that at least one of them maintains integrity. I've found correctable errors (only a tiny part of the file corrupted) rather rare, compared to losing entire media, especially when using Flash (cards, USB sticks) for backups.
There are many
filesystems with error detection and correction built-in, so one option is to use a filesystem image (via a loopback device) to store the data. Essentially, you use
losetup to setup a block device backed by your filesystem image. Initially, you format it with the desired filesystem, and then mount the loopback device, at which point it becomes accessible. Afterwards, you unmount the filesystem,
fsync to ensure the image is sync'd to storage media, and detach the loop device. Of course, if you use dedicated media like Flash or spinny-rust drives, it'd make sense to format the device with that filesystem in the first place.
If there was an actual use case for individual bit flips (as opposed to entire sectors lost), one could use e.g.
libcorrect to write an utility that optionally compresses the input file, then generates an output file with Reed-Solomon codes, and another that decodes such files and optionally decompresses it.
libcorrect is often used for Software Defined Radio (SDR), and regardless of the recent infrastructure attack on xz-utils, I would use
xz as the optional precompressor/postdecompressor.