# Why are checksums used if they're flawed?

Consider an overly simple example:

Say we want to calculate the checksum of "hi". Since h is the 8th letter of the alphabet, we'll say h=8, and similarly, i=9. So the checksum of hi is 8+9=17.

1) What if i is accidentally flipped to j, but it's balanced out by the fact that h gets flipped to g?

2) What if i gets flipped to j, but the checksum itself also gets corrupted and ends up being 18?

It seems that checksums can allow you to strongly suspect something, but not be certain. If so, why are they used if we need certainty?

• Because there is no certainty, and something is better than nothing. You could use a duplicate as a checksum, but there is still a possibility that both the original and the checksum copy will have identical errors. It is smaller than conventional checksums, but it takes bandwidth and time that is excessive. Mar 3, 2017 at 18:50
• "Because there is no certainty" - so is TCP not 100% reliable, then? Mar 3, 2017 at 18:52
• TCP is reliable in the fact that packets get delivered, and the data are given to the application process in the correct order. It is up to the application to determine if the data are correct. Mar 3, 2017 at 18:53
• Ah I understand now - thanks Ron. (This seems to be an answer to me; if you want to make it into an answer, I'll accept it.) Mar 3, 2017 at 18:59
• Remember the odds of a collision are approximately 1/(2^32). That's not certainty, but it's certainly the way to bet ;-p Mar 3, 2017 at 19:28

When transmitting TCP over IPv4 over Ethernet, there are three levels where checksum (or CRC) is used:

• Ethernet has 32-bit CRC called frame check sequence (FCS). This is very reliable: for random corruption, it means that 1 in 4 billion packets gets accidentally accepted even though it contains corrupted data. Considering that one packet is typically about a kilobyte, this means that random corruption corrupts your data once per 4 terabytes of corrupted data sent. Unfortunately, Ethernet's FCS is not true end-to-end checksum.
• IPv4 has 16-bit header checksum. It is calculated using the Internet checksum algorithm. It is much less reliable than Ethernet's FCS, and each router must modify the packet by decrementing hop count (and thus recalculating checksum), so this is not true end-to-end checksum either. Due to the additional workload required on routers, IPv6 has eliminated this checksum.
• TCP has 16-bit whole data checksum protecting some parts of the IPv4 header, TCP header and all of the data. This is a true end-to-end checksum calculated using the same algorithm as IPv4 header checksum. Unfortunately, there is one in 65536 chance of accepting random corruption, meaning that 64 megabytes of randomly corrupted data sent will be once accepted given a kilobyte segment size.

Because data can be corrupted when in the computer's packet buffer memory, not just when traveling over a link, good protocols implement their own checksumming even when operating over TCP, as the checksum of TCP is not that reliable. None of these three checksums are cryptographic quality. For example, the Git version control system protects all data using cryptographic quality SHA-1 (that unfortunately has been recently found to suffer from collisions...)

If TCP was designed today, it surely would use a 32-bit or even 64-bit CRC instead of the 16-bit Internet checksum.

There is no absolute reliability of data. A checksum is a relatively small and fast way of providing some security that the data are correct, but it is up to the application to ensure that.

TCP does use a checksum, but it does not guarantee the data are correct. The reliability of TCP is because TCP guarantees that the segments are delivered and presented to the application in the proper order. It has mechanisms for requesting lost segments, and it can reorder out-of-order segments.