I wrote a simple C program to demonstrate the checksum error detection technique in computer networks. To do this, I used the char
datatype in C, #define
'd it to byte
and ran the code. For some reason, I'm getting a weird bug where the corrupted byte is being printed such that it has a difference of "FFFFFF80" with the original byte.
This is the code that I'm running:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
#define byte char
#define MAX_STRING 0xFFFF
#define BYTE_SIZE 8
#define min(a, b) a < b ? a : b
byte *corrupt_string(byte *string, int length, int bits);
void print_string(byte *string, int length);
byte *copy_string(byte *string, int length);
char *make_string(char ch, int repetition);
void debug_corruption(byte *target, byte *source, int length);
bool is_corrupt(byte *target, byte *source, int length);
int main(int argc, char **argv)
{
byte *input, *corrupted;
int input_length;
if (argc != 2)
{
printf("Usage: <bin> \"<data string>\"");
return EXIT_FAILURE;
}
srand(time(NULL));
input = argv[1];
input_length = strnlen_s(input, MAX_STRING);
corrupted = corrupt_string(copy_string(input, input_length),
input_length, 1);
debug_corruption(corrupted, input, input_length);
printf("\n%s\nResult\t\t\t: ", make_string('-', 0x80));
if (is_corrupt(input, corrupted, input_length))
printf("String is corrupted\n");
else
printf("String is not corrupted\n");
return EXIT_SUCCESS;
}
byte *corrupt_string(byte *string, int length, int bits)
{
int i;
for (i = 0; i < bits; i++)
{
int index = rand() % length;
int bit_pos = rand() % BYTE_SIZE;
if (rand() % 2 == 0)
{
continue;
}
string[index] ^= ((byte)1 << bit_pos);
}
return string;
}
void print_string(byte *string, int length)
{
int i, i_max = min(length, MAX_STRING) - 1;
for (i = 0;; i++)
{
if (string[i] == 0)
printf("..");
else
printf("%02X", string[i]);
if (i == i_max)
return;
printf(" ");
}
}
byte *copy_string(byte *string, int length)
{
byte *result = (byte *)calloc(length, sizeof(byte));
memcpy_s(result, length, string, length);
return result;
}
char *make_string(char ch, int repetition)
{
char *result;
if (repetition <= 0)
{
return "";
}
result = (char *)calloc(repetition + 1, sizeof (char));
memset(result, ch, repetition * sizeof (char));
result[repetition] = 0;
return result;
}
void debug_corruption(byte *target, byte *source, int length)
{
int i;
byte *diff_string;
printf("Before corruption\t: ");
print_string(source, length);
printf("\n\nAfter corruption\t: ");
print_string(target, length);
diff_string = (byte *)calloc(length, sizeof(byte));
for (i = 0; i < length; i++)
{
byte diff = (byte)abs(source[i] - target[i]);
diff_string[i] = diff;
}
printf("\n%s\nCorrupted parts\t\t: ", make_string('-', 0x80));
print_string(diff_string, length);
printf("\n");
}
bool is_corrupt(byte *target, byte *source, int length)
{
byte check_sum1 = (byte)0, check_sum2;
for (int i = 0; i < length; i++)
{
check_sum1 += source[i];
}
check_sum1 = -check_sum1;
check_sum2 = check_sum1;
for (int i = 0; i < length; i++)
{
check_sum2 += target[i];
}
return (check_sum2 != 0);
}
And here's some outputs that got the error(including the command line arguments): https://pastebin.com/mwQjZ1yD