Thread: Creating Hamming code for an ASCII character

  1. #1
    Registered User
    Join Date
    Feb 2015
    Posts
    23

    Creating Hamming code for an ASCII character

    I need to create a program that creates a hamming code for a series of 7 bit ASCII char from the command line, flips a bit as determined from the corresponding number on the command line, and then corrects the code.

    I'm up to the creating hamming code part.

    All of my functions except for createHamming() work as intended for the time being, so don't worry about anything except that function. I just included all the code so that people can run it.

    I did have it generating the Hamming code correctly, but when I put code that was previously in the createHamming() function into their own functions (the four methods that check parity using the four check bits) to increase readability/modularity every thing went haywire. The hamming code is now being made to be like 20+ bits long when it should be 11 bits. The loops that set the bits don't go higher than 10 so I don't know how thats even in the realm of possibilities. Does anyone have any idea whats wrong?
    Code:
    /*==========================================================
     *
     * Program Purpose: To read a short ASCII string from the command 
     * line along with a series of integers. It creates a Hammming code 
     * for each character and then flips the bit at a position determined by 
     * the corresponding number from the command line. It then 
     * corrects the code. 
     * 
     *============================================================
     */
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <math.h>
    
    
    typedef unsigned long set;
    
    
    int countArgs(int argc, char **argv);
    void printBits(set a);
    set decStrToSet(char dec[]);
    set flipBit(set a, int bit);
    set createHamming(set a);
    set checkAndCorrectBits(set a);
    int checkBit1(set b);
    int checkBit2(set b);
    int checkBit3(set b);
    int checkBit4(set b);
    
    
    int main(int argc, char *argv[]){
        if(argc < 2){
            //command line must have at least three arguments (one 
            //char, one integer)
             printf("Error: invalid number of arguments\n");
             exit(1);
        }
    
    
         char chars[256];
         int nums[256];
         
         strcpy(chars, argv[1]);//initializes chars with first word
         strcat(chars, " ");//contatenates space between words
         
         int i = 2;//loop starts with second word
         int numWords = 1; //the number of words from command line
         
         //copies all words from command line
         while(isalpha(argv[i][0])){
             strcat(chars, argv[i]);//concatenates current argument to chars array
             strcat(chars, " ");//contatenates space between words
             
             numWords++;
             i++;
        }
                
        //copies numbers to int array
        int j = 0; //index where current number is added
        for(i = numWords + 1; i < argc; ++i){
            nums[j] = decStrToSet(argv[i]);
             j++;
        }
        
        for(i = 0; i <= numWords; i++){//loops through chars
            
            printf("The bit pattern for %c is: ", chars[i]);
            printBits((set)(chars[i]));
            
            set a = createHamming((set)(chars[i]));
            
            printf("The Hamming code for %c is: ", chars[i]);
            printBits(a);
            
            a = flipBit(a, nums[i]);
            
            printf("Flipped bit %d. The recieved code is: ", nums[i]);
            printBits(a);
                
            printf("The check bits are ");
            a = checkAndCorrectBits(a);
            
            printf("The corrected code is: ");
            printBits(a);
            
            printf("\n\n");
        }    
            
        return 0;
    }
    
    
    set checkAndCorrectBits(set a){
        //checks the bits, prints the results of the check bits and the bit in error
        //corrects the erroneous bit and returns the corrected set
        set b;
        return b;
    }
    
    
    set flipBit(set a, int bit){
        //flips the bit at the position indicated by int bit
    }
    
    set createHamming(set a){
    	//creates hamming code (odd parity) for set
    	
    	set b;
    	int set[4];//determines what check bits should be set 
    	
    	printf("Hamming code with 0's at check bits:\n");//DEBUG
    		
    	//creates binary code of appropriate length with 0's at check bits
    	int i = 0;
    	int k = 6; //index of set a 
    
    
    	for(i = 10; i >= 0; i--){
    		//sets check bits to zero
    		if(i == 0 || i == 1 || i == 3 || i == 7){
    			b &= ~(1 << i); //clears the i-th bit of set b	
    			printf("Setting check bit to zero: ");//DEBUG
    			printf("0\n");//DEBUG
    		}
    		//sets data bits
    		else{
    			if(a & (1 << k)){
    				b |= 1 << i; //sets the i-th bit of set b
    				printf("Setting data bit to one: ");//DEBUG
    				printf("1\n");//DEBUG
    			}
    			else{
    				b &= ~(1 << i); //clears the i-th bit of set b
    				printf("Setting data bit to zero: ");//DEBUG
    				printf("0\n");//DEBUG
    				
    			}
    			
    			k--;
    		}
    	}
    	
    	//determines what check bits yield odd parity
    	//first check bit
    	set[0] = checkBit1(b);
    	
    	//second check bit
    	set[1] = checkBit2(b);
    	
    	//third check bit
    	set[2] = checkBit3(b);
    	
    	//fourth check bit
    	set[3] = checkBit4(b);
    	
    	//creates hamming code
    	i = 0;
    	int j = 3; //index of set[]
    	for(i = 10; i >= 0; i--){
    		//sets check bits
    		if(i == 0 || i == 1 || i == 3 || i == 7){//if i is check bit
    			if(set[j] == 0){//if the check bit does NOT return odd parity
    				b |= 1 << i; //sets the i-th bit of set b
    				printf("Setting check bit %d\n", (i + 1));//DEBUG
    			}	
    			
    			j--;
    		}
    	}
    	
    	return b;
    }
    
    set decStrToSet(char dec[]){
        //converts dec string to set 
        char *ptr;
    
    
        set a = strtol(dec, &ptr, 10);
    
    
        return a;
    }
    
    
    void printBits(set a){
        //prints the bits of a set
        //does not print leading zeroes
        
        int print = 0; //boolean, set to 1 when ready to print
        int i = 0;
        int check4 = 2; //checks if 4 digits have been printed, if so loop prints space
        
        for(i = 31; i >= 0; i--){
            if(a & (1 << i)){ //checks if i-th bit is set (starting at 0))
                print = 1;
                printf("1");
            }
            else if(print == 1){//prints 0's only if it is NOT a leading zero
                printf("0");
            }
            
            if(print == 1){
                if(check4 == 4){
                    printf(" ");
                    check4 = 0;
                }
                
                check4++;
            }
            
            
        }
        
        printf("\n");
    }
    
    
    int checkBit1(set b){
        //returns 1 if the first check bit returns odd parity, 0 else
        int num = 0;
        int sum = 0;
        int i = 0;
        for(i = 0; i < 11; i++){
            if((i + 1) % 2 != 0){//for odd positions
                if(b & (1 << i)){
                    sum++;
                }
            }    
        }
        if(sum % 2 == 0){
            num = 0;
        }
        else{
            num = 1;
        }
        
        printf("Sum: %d, is odd: %d\n", sum, num);
        
        return num;
    }
    
    
    int checkBit2(set b){
        //returns 1 if the second check bit returns odd parity, 0 else
        int num = 0;
        int sum = 0;
        int check = 1; //counts how many bits have been checked. If < 0, then bit is not checked
        int i = 0;
        for(i = 1; i < 11; i++){
            if(check > 0){
                if(b & (1 << i)){
                    sum++;
                }
            }
            
            if(check == 2){//if two have been checked, then goes back to skip mode
                check = -2;
            }
            check++;
        }
        if(sum % 2 == 0){
            num = 0;
        }
        else{
            num = 1;
        }
        
        printf("Sum: %d, is odd: %d\n", sum, num);//DEBUG
        
        return num;
    }
    
    
    int checkBit3(set b){
        int sum = 0;
        int check = 1;
        int i = 0;
        int num = 0;
        for(i = 3; i < 11; i++){
            if(check > 0){
                if(b & (1 << i)){
                    sum++;
                }
            }
            
            if(check == 4){//if four have been checked, then goes back to skip mode
                check = -4;
            }
            check++;
        }
        if(sum % 2 == 0){
            num = 0;
        }
        else{
            num = 1;
        }
        
        printf("Sum: %d, is odd: %d\n", sum, num);//DEBUG
        
        return num;
    }
    
    
    int checkBit4(set b){
        int sum = 0;
        int check = 1;
        int i = 0;
        int num = 0;
        for(i = 7; i < 11; i++){
            if(check > 0){
                if(b & (1 << i)){
                    sum++;
                }
            }
            
            if(check == 8){//if eight have been checked, then goes back to skip mode
                check = -8;
            }
            check++;
        }
        if(sum % 2 == 0){
            num = 0;
        }
        else{
            num = 1;
        }
        
        printf("Sum: %d, is odd: %d\n", sum, num);//DEBUG
        
        return num;    
    }
    Sample input:
    lab3 Hi 0 9

    Sample output:
    The bit pattern for H is: 100 1000
    Hamming code with 0's at check bits:
    Setting data bit to one: 1
    Setting data bit to zero: 0
    Setting data bit to zero: 0
    Setting check bit to zero: 0
    Setting data bit to one: 1
    Setting data bit to zero: 0
    Setting data bit to zero: 0
    Setting check bit to zero: 0
    Setting data bit to zero: 0
    Setting check bit to zero: 0
    Setting check bit to zero: 0
    Sum: 2, is odd: 0
    Sum: 2, is odd: 0
    Sum: 1, is odd: 1
    Sum: 1, is odd: 1
    Setting check bit 2
    Setting check bit 1
    The Hamming code for H is: 100 0000 0010 0100 0110 0010 0001 1
    Flipped bit 0. The recieved code is: 100 0000 0010 0100 0110 0010 0001 1
    The check bits are The corrected code is: 1




    The bit pattern for i is: 110 1001
    Hamming code with 0's at check bits:
    Setting data bit to one: 1
    Setting data bit to one: 1
    Setting data bit to zero: 0
    Setting check bit to zero: 0
    Setting data bit to one: 1
    Setting data bit to zero: 0
    Setting data bit to zero: 0
    Setting check bit to zero: 0
    Setting data bit to one: 1
    Setting check bit to zero: 0
    Setting check bit to zero: 0
    Sum: 3, is odd: 1
    Sum: 4, is odd: 0
    Sum: 1, is odd: 1
    Sum: 2, is odd: 0
    Setting check bit 8
    Setting check bit 2
    The Hamming code for i is: 100 0000 0010 0100 0111 0110 0011 0
    Flipped bit 9. The recieved code is: 100 0000 0010 0100 0111 0110 0011 0
    The check bits are The corrected code is: 1
    Last edited by PsylentKnight; 02-24-2015 at 04:43 PM.

  2. #2
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    A Hamming code can be generated using a matrix multiply that uses AND and XOR for the math operations.

    Wiki articles:

    Hamming code - Wikipedia, the free encyclopedia

    Hamming(7,4) - Wikipedia, the free encyclopedia
    Last edited by rcgldr; 02-24-2015 at 05:23 PM.

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Quote Originally Posted by PsylentKnight View Post
    Code:
    set decStrToSet(char dec[]){
        //converts dec string to set 
        char *ptr;
    
        set a = strtol(dec, &ptr, 10);
    
        return a;
    }
    Why you declare 'char *ptr' if you don't need it?
    You can define your function as:
    Code:
    set decStrToSet(char dec[]){
        //converts dec string to set 
        return strtol(dec, NULL, 10);
    }
    In your function 'createHamming()' you declare b, but b was never defined.
    A few lines later, you work on undefined b. The result will also be undefined.
    You should define b before you work with it.
    Code:
    …
        set b = 0;
    …
    Other have classes, we are class

  4. #4
    Registered User
    Join Date
    Feb 2015
    Posts
    23
    The last 11 bits of the hamming code in the output are correct, its just that its got all those extra bits in front of it and I don't know where those are coming from. I can get it to display correctly by only having it print 11 bits, but I'd still like to know what's going on.

    EDIT: Thanks so much. I knew it was going to be something simple but I had no idea what. So the bits at the front are just whatever garbage is left over from the last time the program ran or something?
    Last edited by PsylentKnight; 02-24-2015 at 06:27 PM.

  5. #5
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Yes, it's garbage value that was in the memory before your program used the memory.
    I have not checked the comlete code. It could be that other functions have also this problem.
    Other have classes, we are class

  6. #6
    Registered User
    Join Date
    Feb 2015
    Posts
    23
    No, I've since made sure all my variables are initialized. I just didn't know that C didn't have a garbage collector (Java is my first language).

    I've got the entire program working now, thanks for the help. That one little thing was about to drive me insane.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to assign an ASCII character via inline assembly code
    By LanguidLegend in forum C Programming
    Replies: 5
    Last Post: 04-19-2011, 12:32 PM
  2. Replies: 3
    Last Post: 01-25-2006, 08:04 PM
  3. covert ascii code to character
    By Shadow in forum C Programming
    Replies: 2
    Last Post: 04-25-2002, 09:53 PM
  4. How to return the ASCII code value of a character in C?
    By DramaKing in forum C Programming
    Replies: 3
    Last Post: 02-11-2002, 12:06 PM
  5. ASCII code for a NULL character
    By GaPe in forum C Programming
    Replies: 1
    Last Post: 12-09-2001, 05:40 AM