#include <stdio.h>
#include <string.h>

// Max size for data and polynomial
#define MAX 100

char t[MAX], cs[MAX], g[] = "1011"; 
int a, e, c;

// Function to perform XOR operation
void xor_func() {
    int N = strlen(g);
    for (c = 1; c < N; c++) {
        cs[c] = ((cs[c] == g[c]) ? '0' : '1');
    }
}

// Function to calculate CRC/Remainder
void crc_calc() {
    int N = strlen(g);
    // Initialize cs with the first N bits of t
    for (e = 0; e < N; e++) {
        cs[e] = t[e];
    }
    
    int next_bit = N;
    do {
        if (cs[0] == '1') {
            xor_func();
        }
        
        // Shift bits left by 1
        for (c = 0; c < N - 1; c++) {
            cs[c] = cs[c + 1];
        }
        // Pull the next bit from the data
        cs[c] = t[next_bit++];
        
    } while (next_bit <= a + N - 1);
}

int main() {
    // Clear arrays
    memset(t, 0, MAX);
    memset(cs, 0, MAX);

    printf("Enter data bits: ");
    scanf("%s", t);

    a = strlen(t); // Original data length
    int N = strlen(g); // Polynomial length
    
    printf("\nGenerating polynomial: %s", g);
    
    // Append N-1 zeros to the data (Padding)
    for (e = a; e < a + N - 1; e++) {
        t[e] = '0';
    }
    t[e] = '\0';

    printf("\nData after padding: %s", t);

    crc_calc(); // Calculate Checksum

    printf("\nCalculated Checksum: %s", cs);
    
    // Replace the padding bits with the actual checksum bits
    for (e = a; e < a + N - 1; e++) {
        t[e] = cs[e - a];
    }
    
    printf("\nFinal Codeword to be sent: %s", t);
    printf("\n---------------------------------------");

    // Error simulation
    printf("\nTest error detection? (1 for Yes, 0 for No): ");
    int choice;
    scanf("%d", &choice);

    if (choice == 1) {
        printf("Enter bit position to flip (1 to %d): ", (int)strlen(t));
        int pos;
        scanf("%d", &pos);
        if(pos > 0 && pos <= (int)strlen(t)) {
            t[pos - 1] = (t[pos - 1] == '0') ? '1' : '0';
            printf("Data with error: %s", t);
        }
    }

    crc_calc(); // Recalculate to verify

    // Check if remainder (cs) is all zeros
    int error_found = 0;
    for (e = 0; e < N - 1; e++) {
        if (cs[e] == '1') {
            error_found = 1;
            break;
        }
    }

    printf("\n---------------------------------------");
    if (error_found) {
        printf("\nRESULT: Error detected (Remainder is not 0)");
    } else {
        printf("\nRESULT: No error detected (Data is clean)");
    }
    printf("\n---------------------------------------\n");

    return 0;
}