A parity bit keeps the count of 1s even; doing it per row and column locates a single flipped bit.
A checksum is any small value computed from data and sent alongside it, so the receiver can recompute it and verify nothing changed in transit. The simplest checksum of all is a single parity bit — and building it up into two dimensions turns pure error *detection* into error *correction*.
Under even parity, you append one extra bit chosen so the group holds an even number of 1s. The receiver counts the 1s: if the total is odd, at least one bit flipped in transit. It's cheap and it always catches a single-bit error — but it has a blind spot: if *two* bits flip, the count stays even and the error slips through. A single parity bit also can't tell you *which* bit is wrong.
Arrange the data as a grid and compute a parity bit for every row and every column (this is 2D parity, also called a longitudinal redundancy check or LRC). Now a single flipped bit breaks the parity of exactly one row *and* one column. Where that failing row and failing column cross is the corrupted bit — so you not only detect it, you can flip it back and correct it.
data + row parity a single flip at (row 2, col 3)
1 0 1 1 | 1 1 0 1 1 | 1 ok
0 1 1 0 | 0 --> 0 1 0 0 | 0 row 2 FAILS
1 1 0 1 | 1 1 1 0 1 | 1 ok
--------- col parity
0 0 0 0 0 0 1 0
^ col 3 FAILS
intersection (row 2, col 3) = the corrupted bit