home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / ddjmag / ddj8606.arc / MARASCO.JUN < prev    next >
Encoding:
Text File  |  1986-06-30  |  4.6 KB  |  186 lines

  1. /*
  2.  * short demo program to illustrate Hamming forward error correction 
  3.  * code detects and corrects all one bit errors and detects two
  4.  * bit errors in a total transmitted block of 16 bits.
  5.  * eleven bits are message bits, the rest are error checks
  6.  *
  7.  * implementation is oriented toward exposition, not speed or
  8.  * efficiency -- this is not industrial strength code!
  9.  * 
  10.  * bit fields not implemented in C/80
  11.  * 
  12.  * Joe Marasco, March 1986
  13.  */
  14.  
  15. #include "fprintf.h"
  16. #define        EOF    -1
  17.  
  18. #define        B0    1
  19. #define        B1    2
  20. #define        B2    4
  21. #define        B3    8
  22. #define        B4    16
  23. #define        B5    32
  24. #define        B6    64
  25. #define        B7    128
  26. #define        B8    256
  27. #define        B9    512
  28. #define        B10    1024
  29. #define        B11    2048
  30. #define        B12    4096
  31. #define        B13    8192
  32. #define        B14    16384
  33. #define        B15    32768
  34.  
  35. #define        C1    (B1 + B3 + B5 + B7 + B9 + B11 + B13 + B15)
  36. #define        C2    (B2 + B3 + B6 + B7 + B10 + B11 + B14 + B15)
  37. #define        C3    (B4 + B5 + B6 + B7 + B12 + B13 + B14 + B15)
  38. #define        C4    (B8 + B9 + B10 + B11 + B12 + B13 + B14 + B15)
  39.  
  40. main()
  41. {
  42.         int    input[11] ;    /* input message bits    */
  43. register unsigned int    xmit ;        /* transmitted message    */
  44.         int    recvd[16] ;    /* received message bits*/
  45. register unsigned int    rec ;        /* received message    */
  46.         int    syndrome ;    /* computed syndrome    */
  47.         int    recpar    ;    /* parity of rec'd msg    */
  48.                int    i , ch ;
  49.                 
  50.     for (;;) {
  51.         
  52.         printf("input 11 message bits, ^C to quit\n") ;
  53.         printf("1 2 3 4 5 6 7 8 9 0 1\n") ;
  54.  
  55.         i = 0 ;
  56.         while ( ((ch = getchar()) != EOF) && i<11 )
  57.             switch(ch) {
  58.             case '0' :     input[i++] = 0 ; 
  59.                     break ;
  60.             case '1' :     input[i++] = 1 ; 
  61.                     break ;
  62.             }
  63. /*
  64.  * anything but a 0 or 1 is ignored 
  65.  * check that we have 11 good bits  
  66.  */
  67.         if ( i < 11 ) {
  68.             printf("not enough valid bits, try again\n") ;
  69.             continue ;
  70.         }
  71. /*
  72.  * build the message
  73.  */
  74.         xmit = 0 ;
  75.         xmit |= input[0] << 3 ;
  76.         xmit |= input[1] << 5 ;
  77.         xmit |= input[2] << 6 ;
  78.         xmit |= input[3] << 7 ;            
  79.         xmit |= input[4] << 9 ;
  80.         xmit |= input[5] << 10 ;
  81.         xmit |= input[6] << 11 ;
  82.         xmit |= input[7] << 12 ;
  83.         xmit |= input[8] << 13 ;
  84.         xmit |= input[9] << 14 ;
  85.         xmit |= input[10] << 15 ;
  86. /* 
  87.  * and the check bits -- even parity
  88.  */
  89.         xmit |= (parity( C1 & xmit ) << 1) |
  90.             (parity( C2 & xmit ) << 2) |
  91.             (parity( C3 & xmit ) << 4) |
  92.             (parity( C4 & xmit ) << 8)  ;
  93. /*
  94.  * and last but not least, make total parity even
  95.  */
  96.         xmit |= parity( xmit ) ;
  97. /*
  98.  * display it
  99.  */
  100.         printf("the block sent is                %x \n", xmit ) ;
  101.         printf("0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n") ;
  102.         for (i=0 ; i<16 ; ++i)
  103.             printf("%d ", ((xmit>>i) & 01) ) ;
  104.         printf("\n") ;
  105.         printf("now input the received block\n") ;
  106.         printf("0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n") ;
  107. /* 
  108.  * get the received message
  109.  */
  110. readagain:    i = 0 ;
  111.         while ( ((ch = getchar()) != EOF) && i<16 )
  112.             switch(ch) {
  113.             case '0' :     recvd[i++] = 0 ; 
  114.                     break ;
  115.             case '1' :     recvd[i++] = 1 ; 
  116.                     break ;
  117.             }
  118. /*
  119.  * anything but a 0 or 1 is ignored 
  120.  * check that we have 16 good bits  
  121.  */
  122.         if ( i < 16 ) {
  123.             printf("not enough valid bits, try again\n") ;
  124.             goto readagain ;
  125.         }
  126.         for (i=0 , rec=0 ; i<16 ; ++i )
  127.                 rec |= (recvd[i] << i) ;
  128.         printf("the block received is            %x \n", rec ) ;
  129. /* 
  130.  * compute the syndrome
  131.  */
  132.         syndrome =   parity( C1 & rec ) |
  133.                ( parity( C2 & rec ) << 1 ) |
  134.                ( parity( C3 & rec ) << 2 ) |
  135.                ( parity( C4 & rec ) << 3 )  ;        
  136. /* 
  137.  * and the parity bit, which should be zero
  138.  */    
  139.         recpar = parity( rec ) ;
  140. /*
  141.  * decision time
  142.  */
  143.         if ( syndrome == 0 ) {
  144.             printf("good message!\n") ;
  145.             if (recpar) {
  146.                 printf("with reversed parity bit\n") ;
  147.                 rec = rec ^ 01 ;
  148.                 printf("the recovered block is           %x\n",
  149.                         rec ) ;
  150.                 printf("0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n") ;
  151.                 for (i=0 ; i<16 ; ++i) 
  152.                     printf("%d ", ((rec>>i) & 01) ) ;    
  153.                 printf("\n") ;
  154.             }                
  155.             printf("---------------------------------\n") ;
  156.         }
  157.         else {
  158.             if (!recpar) {
  159.                 printf("two bit errors, can't fix\n") ;
  160.                 printf("--------------------------------\n") ;
  161.             }
  162.             else {
  163.                 printf("bad bit in position %d\n",
  164.                         syndrome ) ;
  165.                 rec = rec ^ ( 01 << syndrome ) ;
  166.                 printf("the recovered block is           %x\n",
  167.                                 rec ) ;
  168.                 printf("0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5\n") ;
  169.                 for (i=0 ; i<16 ; ++i)   
  170.                     printf("%d ", ((rec>>i) & 01) ) ;
  171.                 printf("\n-------------------------------\n") ;
  172.             }
  173.         }
  174.     }
  175. }
  176. parity( message )
  177. unsigned int message ;
  178. {
  179. /*
  180.  * return 1 if odd parity, 0 if even
  181.  */
  182.     int j , k ;
  183.     for ( j=0 , k=0 ; j<16 ; ++j ) k += ( (message >> j) & 01 ) ;
  184.     return( k & 01 ) ;
  185. }
  186.