Skip to content

How to Implement Checksum Using Python

Learn how to implement a checksum algorithm in Python for error detection in network data transmission, including sender-side generation and receiver-side verification.

A checksum is an error detection method widely used in computer networks. It allows the sender to generate a small fixed-size value from a message, which the receiver then uses to verify whether the data arrived intact. If even a single bit changes during transmission, the checksum will detect the discrepancy.

Checksums operate at the higher layers of the network protocol stack (such as TCP, UDP, and IP) and involve two components:

  • Checksum Generator (sender side): Computes a checksum from the original message and appends it to the data before sending.
  • Checksum Checker (receiver side): Recomputes the checksum from the received data and verifies it against the transmitted checksum.

In this guide, you will learn how the checksum algorithm works step by step and how to implement both the sender and receiver sides in Python.

How the Checksum Algorithm Works

Sender Side: Generating the Checksum

  1. Divide the message into fixed-size segments of k bits each.
  2. Add all segments together using binary addition.
  3. If the sum has more than k bits, wrap around by adding the overflow bits back to the remaining k bits.
  4. Complement the final sum (flip all bits: 1 → 0, 0 → 1). This is the checksum.
  5. Send the original message along with the checksum.

Receiver Side: Verifying the Checksum

  1. Divide the received message into the same k-bit segments.
  2. Add all segments together with the received checksum.
  3. Handle any overflow by wrapping around, just like on the sender side.
  4. Complement the result.
  5. If the final value is all zeros, the data is accepted (no error detected). Otherwise, an error is detected and the data is rejected.

Implementing the Checksum Generator

The sender divides the message into segments, sums them, handles overflow, and complements the result:

def find_checksum(message, k):
    """
    Compute the checksum for a binary message string.
    
    Args:
        message: A binary string (e.g., '10010101011000111001010011101100')
        k: The segment size in bits (e.g., 8)
    
    Returns:
        The checksum as a binary string of length k.
    """
    segments = [message[i:i + k] for i in range(0, len(message), k)]

    total = sum(int(seg, 2) for seg in segments)
    binary_sum = bin(total)[2:]  # Remove '0b' prefix

    while len(binary_sum) > k:
        overflow = len(binary_sum) - k
        binary_sum = bin(int(binary_sum[:overflow], 2) + int(binary_sum[overflow:], 2))[2:]

    binary_sum = binary_sum.zfill(k)

    checksum = ''.join('0' if bit == '1' else '1' for bit in binary_sum)

    return checksum

Key details:

  • bin(total)[2:] converts an integer to its binary string representation and strips the '0b' prefix.
  • The while loop handles cases where the sum overflows beyond k bits by repeatedly folding the overflow back in.
  • .zfill(k) ensures the result is zero-padded to exactly k bits.

Implementing the Checksum Checker

The receiver performs the same segmentation and addition, but also includes the received checksum in the sum:

def verify_checksum(received_message, k, checksum):
    """
    Verify the integrity of a received message using its checksum.
    
    Args:
        received_message: The binary message string received.
        k: The segment size in bits.
        checksum: The checksum received from the sender.
    
    Returns:
        The complement of the receiver's sum. All zeros means no error.
    """
    segments = [received_message[i:i + k] for i in range(0, len(received_message), k)]

    total = sum(int(seg, 2) for seg in segments) + int(checksum, 2)
    binary_sum = bin(total)[2:]

    while len(binary_sum) > k:
        overflow = len(binary_sum) - k
        binary_sum = bin(int(binary_sum[:overflow], 2) + int(binary_sum[overflow:], 2))[2:]

    binary_sum = binary_sum.zfill(k)

    result = ''.join('0' if bit == '1' else '1' for bit in binary_sum)

    return result

If the returned string is all zeros ('00000000' for k=8), the data passed the integrity check.

Complete Implementation with Error Detection

Here is the full program combining both sender and receiver logic, along with the final acceptance/rejection decision:

def find_checksum(message, k):
    """Compute the checksum for a binary message."""
    segments = [message[i:i + k] for i in range(0, len(message), k)]
    total = sum(int(seg, 2) for seg in segments)
    binary_sum = bin(total)[2:]

    while len(binary_sum) > k:
        overflow = len(binary_sum) - k
        binary_sum = bin(int(binary_sum[:overflow], 2) + int(binary_sum[overflow:], 2))[2:]

    binary_sum = binary_sum.zfill(k)
    checksum = ''.join('0' if bit == '1' else '1' for bit in binary_sum)
    return checksum


def verify_checksum(received_message, k, checksum):
    """Verify the received message against the checksum."""
    segments = [received_message[i:i + k] for i in range(0, len(received_message), k)]
    total = sum(int(seg, 2) for seg in segments) + int(checksum, 2)
    binary_sum = bin(total)[2:]

    while len(binary_sum) > k:
        overflow = len(binary_sum) - k
        binary_sum = bin(int(binary_sum[:overflow], 2) + int(binary_sum[overflow:], 2))[2:]

    binary_sum = binary_sum.zfill(k)
    result = ''.join('0' if bit == '1' else '1' for bit in binary_sum)
    return result


if __name__ == "__main__":
    sent_message = "10010101011000111001010011101100"
    k = 8

    checksum = find_checksum(sent_message, k)
    print(f"Sender Checksum: {checksum}")

    received_message = "10010101011000111001010011101100"
    receiver_result = verify_checksum(received_message, k, checksum)
    print(f"Receiver Verification Result: {receiver_result}")

    if int(receiver_result, 2) == 0:
        print("STATUS: ACCEPTED- No error detected.\n")
    else:
        print("STATUS: REJECTED- Error detected!\n")

    corrupted_message = "10000101011000111001010011101101"  # Bits changed
    corrupted_result = verify_checksum(corrupted_message, k, checksum)
    print(f"Corrupted Message Verification Result: {corrupted_result}")

    if int(corrupted_result, 2) == 0:
        print("STATUS: ACCEPTED- No error detected.")
    else:
        print("STATUS: REJECTED- Error detected!")

Output:

Sender Checksum: 10000101
Receiver Verification Result: 00000000
STATUS: ACCEPTED- No error detected.

Corrupted Message Verification Result: 00001111
STATUS: REJECTED- Error detected!

Step-by-Step Walkthrough

Let's trace through the algorithm with the example message 10010101011000111001010011101100 and segment size k = 8:

Sender side:

Step Operation Result
1 Divide into 8-bit segments 10010101, 01100011, 10010100, 11101100
2 Convert and sum 149 + 99 + 148 + 236 = 632
3 Binary sum 1001111000 (10 bits- overflows 8)
4 Wrap overflow: 10 + 01111000 01111010 (8 bits)
5 Complement 10000101 ← Checksum

Receiver side (no errors):

Step Operation Result
1 Sum all segments + checksum 149 + 99 + 148 + 236 + 133 = 765
2 Binary sum 1011111101 (10 bits)
3 Wrap overflow: 10 + 11111101 11111111
4 Complement 00000000 ← All zeros = ACCEPTED

Making the Implementation More Flexible

The examples above assume the message length is exactly divisible by k and contains exactly 4 segments. Here's a more robust version that handles any message length:

def find_checksum_flexible(message, k):
    """Handle messages of any length, padding the last segment if needed."""
    remainder = len(message) % k
    if remainder != 0:
        message = message.zfill(len(message) + (k - remainder))

    segments = [message[i:i + k] for i in range(0, len(message), k)]
    total = sum(int(seg, 2) for seg in segments)
    binary_sum = bin(total)[2:]

    while len(binary_sum) > k:
        overflow = len(binary_sum) - k
        binary_sum = bin(int(binary_sum[:overflow], 2) + int(binary_sum[overflow:], 2))[2:]

    binary_sum = binary_sum.zfill(k)
    checksum = ''.join('0' if bit == '1' else '1' for bit in binary_sum)
    return checksum

Complexity Analysis

Aspect Value
Time Complexity O(n), where n is the length of the message. Each bit is processed once during segmentation and summation.
Space Complexity O(n/k) for storing the segments, plus O(k) for the checksum string.

Conclusion

The checksum algorithm provides a straightforward and efficient way to detect transmission errors in computer networks. By dividing a message into fixed-size segments, summing them, and complementing the result, both sender and receiver can verify data integrity with minimal computational overhead.

While checksums cannot detect all possible error patterns, they are fast, easy to implement, and form the foundation of error detection in protocols like TCP, UDP, and IP. For applications requiring stronger error detection, consider using CRC or cryptographic hash functions like SHA-256.

Navigation