Códigos de codificación
del canal


Introducción

      La codificación del canal consiste en 'mapear' (añadir redundancia) la secuencia de datos entrante en una secuencia de entrada al canal y realizar el 'mapeo' inverso a la salida del canal en una secuencia de datos tal que los efectos del ruido estén minimizados.
      La introducción de redundancia en la codificación del canal tiene como finalidad mejorar la fiabilidad de la transmisión.

      Antes de comenzar con la descripción de algunos de estos códigos es conveniente dar unas definiciones:
      - tasa de error: Se define como la relación entre el número de bits erróneos recibidos respecto al número total de bits transmitidos. Una tasa de error aceptable para una transmisión es 10 elevado a la -6.
      - tasa residual de error: Se define como la relación entre el número de bits erróneos no detectados sobre el total de bits emitidos. Mide la capacidad de detectar errores.
      - peso de Hamming: El peso de Hamming W(c) de una palabra de código c se define como el número de bits de esa palabra diferentes de cero.
      - distancia de Hamming: Es la distancia entre dos palabras de código de igual longitud y se define como el número de bits (posición a posición) en los que se diferencian las dos palabras.

      También es necesario hacer una diferenciación entre los distintos tipos de códigos:
      - Códigos sistemáticos: aquellos códigos en los que la palabra de información aparece de forma explícita en la palabra codificada.
      - Códigos no sistemáticos: aquellos códigos en los que la palabra de información no aparece de forma explícita en la palabra codificada.
      - Códigos de bloque: (tienen el mismo significado que en el caso de la codificación de la fuente) aquellos códigos en los que todas las palabras tienen la misma longitud y la codificación se hace de forma estática.
      - Códigos lineales: aquellos en los que cualquier combinación lineal de palabras de código válida (por ejemplo la suma módulo 2) produce otra palabra válida.
      - Códigos cíclicos: aquellos en los que cualquier desplazamiento cíclico de una palabra de código da lugar a otra palabra de código.




Códigos de paridad

      Se basan en añadir un bit a la secuencia a enviar de forma que el número de "1's" sea par o impar, dependiendo del tipo de paridad:
                   - si la paridad es par, el número final de "1's" debe ser par
                   - si la paridad es impar, el número final de "1's" debe ser impar
      Es un código sistemático. Sólo será detector (vuelta atrás) y detectará los errores producidos en un número impar de bits. Si por ejemplo se producen 2 bits erróneos, este código no los detectará.

Ejemplo

paridad par :            1011101 1
paridad impar :         1011101 0






Códigos m entre n

      Un código m entre n se caracteriza porque todas las palabras de código tienen la misma longitud de m bits, de los cuales, n bits son "1's". Es un código sistemático. Sólo será detector (vuelta atrás) y detectará los errores producidos en un número impar de bits. Si por ejemplo se producen 2 bits erróneos, este código no los detectará.

Ejemplo

3 "1's" entre 5 bits:                    011   01
                                                100   11
                                                111   00






Códigos de bloque lineales sistemáticos

      Un código de bloque lineal sistemático será capaz de detectar X-1 bits erróneos, donde X viene dado por la distancia de Hamming mínima entre 2 palabras cualesquiera del código, y será capaz de corregir (X-1)/2 bits erróneos.
      Estos códigos cumplen la siguiente propiedad:
      La suma módulo-2 de dos palabras del código da lugar a otra palabra de código.

      En la especificación de estos códigos se utiliza la siguiente notación:

(n,k)
                   - n es el tamaño de la palabra codificada
                   - k es el tamaño del mensaje original. Estos k bits se envían sin alterar
                   - los n-k bits restantes son los bits de paridad. Es la redundancia mediante la cual se
                   detectan y corrigen los errores


      La forma de una palabra de código de un código de bloque lineal sistemático es la siguiente:
m0m1 . . . mk-1b0b1 b2 . . . bn-k-1

      donde m0.......................mk-1 son los bits del mensaje original y b0.......................bn-k-1 son los bits de paridad que se añaden como redundancia.
      De esta forma, podemos expresar una palabra de código como:
c0c1 . . . cn-k-1cn-k . . . cn-1

      El cálculo de los bits de paridad se realiza de la siguiente forma:
bi = P0i m0 + P1i m 1 + . . . + Pk-1i mk-1

      donde los Pij deben ser tales que la matriz generadora del código tenga filas independientes y las ecuaciones de paridad sean iguales.
      Para realizar la codificación se utiliza una notación matricial.
      Consideraremos la palabra original, la palabra formada por los bits de paridad y la palabra de código como vectores:
                   m = (m0m1 . . . mk-1)
                   b = (b0b1 . . . bn-k-1)
                   c = (c0c1 . . . cn-1)

      También se utiliza la matriz de coeficientes:


      Para realizar la codificación se utiliza la matriz generadora:

G = [ Ik,k | P ]

      Siendo Ik,k la matriz identidad de tamaño kxk.

      De esta forma podemos obtener cada palabra de código a partir de cada palabra de mensaje original realizando la siguiente multiplicación:
c = m ·  G



      Para realizar la decodificación, en destino se recibe un vector (c) de tamaño n y lo que se puede hacer es repetir la operación realizada en la codificación: se toman los primeros k bits y se calcula la redundancia usando la matriz generadora y se comprueba si la redundancia obtenida es igual a la redundancia recibida.

      Otra opción más eficiente es la basada en el concepto de síndrome.
      En el proceso de decodificación basado en el síndrome se utiliza la matriz de chequeo de paridad, que se define de la siguiente forma:
H = [ I | Pt ]

      H tiene la propiedad de que sólo las palabras de código verifican que al multiplicarlas por Ht el resultado es el vector nulo. Esta propiedad será utilizada para la detección y corrección de errores.

      A cada palabra que el receptor recibe a través del canal la denominaremos palabra recibida y la denominaremos r. Una palabra recibida la podemos expresar como:
r = c + e

      Donde c es la palabra de código enviada por el emisor y e es una palabra de error.
      Cada componente ei de la palabra de error podrá valer 1 si hay un error en esa posición y 0 si no lo hay.

      El receptor para realizar la codificación utiliza la matriz H para calcular el vector de síndrome de error a partir de la palabra recibida. El vector de síndrome de error se obtiene de la siguiente forma:
s = r ·  Ht

      El vector de síndrome tiene tantos elementos como bits de paridad se estén usando.
      El vector de síndrome sólo depende de la secuencia de error y no de la palabra de código transmitida.

      Si en la transmisión no se ha producido un error, el síndrome es el vector nulo:
s = r ·  Ht = 0

      Si se ha producido un error la multiplicación de la palabra recibida por Ht nos da un vector que es igual a una de las filas de Ht. La posición que ocupa esa fila es la posición donde hay un error.


      Todas estas operaciones se hacen en módulo-2 (sin acarreo).



      Notas acerca de estos códigos:

      - Para la detección y corrección de errores simples la matriz H debe cumplir:
            1- Todas las columnas de la matriz H deben ser diferentes. Esta condición hace que se
                 pueda localizar la posición del error.
            2- Ninguna de las columnas de H pueden ser todas ceros. Esta condición se debe a que el
                 síndrome es el vector nulo cuando no hay error.

      - Cuando se quieren corregir más de un error, por ejemplo dos errores, la matriz H debe verificar:
            1- Todas las columnas de la matriz H deben ser diferentes
            2- Ninguna de las columnas de H pueden ser todas ceros
            3- La suma de las columnas dos a dos debe ser diferente
                 (Si la matriz H tiene 5 columnas hay 10 sumas diferentes que se pueden hacer. Lo que
                 dice esta propiedad es que todas ellas deben dar resultados diferentes).

      Esta última condición complica el cálculo de códigos correctores de dos bits y en la práctica no se suelen utilizar. Cuando hay más de un error se pedirá una repetición de la secuencia al emisor (vuelta atrás).



      El siguiente applet permite al usuario simular una transmisión utilizando este tipo de códigos:






Código de Hamming

      Un código de Hamming es un código de bloque lineal. Al igual que en los códigos de bloque lineales sistemáticos, podemos denotar un código de Hamming mediante un par (n,k). Sin embargo los valores de n y k deberán verificar una serie de condiciones:
      - n es la longitud de la palabra de código
      - k es el número de bits de datos de la palabra original sin codificar
      - el número de bits de paridad será m = n - k, pero deberá cumplirse la siguiente relación entre
      la longitud de la palabra de código y el número de bits de paridad:

n = 2m - 1    con m >= 3

      - según esto también se cumplirá la siguiente relación entre el número de bits de datos y el
      número de bits de paridad:
k = 2m - m - 1


      Por lo tanto, a cada palabra original la añadiremos unos bits de paridad para obtener la palabra de código, de forma que estos bits de paridad sirvan posteriormente para encontrar y corregir errores que se produzcan en la transmisión.
      Cada uno de los bits de paridad que añadimos a una palabra original va a afectar a unas determinadas posiciones de la nueva palabra de código, de forma que tomarán un valor adecuado para que se cumpla el criterio de paridad (par o impar) preestablecido en las subcombinaciones afectadas por cada uno de estos bits de paridad.
      El siguiente paso consistirá en determinar a que posiciones de los bits de las palabras de código afecta cada bit de paridad. Para ello construiremos todas las combinaciones posibles con m bits de paridad e interpretamos cada una en binario natural:

                                              bm ..................... b3  b2  b1       Posición
0 ....................... 0   0   0 ............ 0
0 ....................... 0   0   1 ............ 1
0 ....................... 0   1   0 ............ 2
0 ....................... 0   1   1 ............ 3
......................................

      Cada bit de paridad va a afectar a aquellas posiciones en las que ese bit vale 1.

                                          Bit de paridad             Posiciones
b1 .................      1,3,5,7,..........
b2 .................      2,3,6,7,..........
..................................................
                                                  bm .................      2m, 2m+1,2m+2,......

      Por último sólo nos queda determinar que posiciones de cada palabra de código ocupará cada bit de paridad. Los bits de paridad han de colocarse en aquellas posiciones en las que no se vean afectados por otros bits de paridad. Estas posiciones serán:

                                                    Bit de paridad         Posición
b1 ...................    20
b2 ...................    21
b3 ...................    22
....................................


      De esta forma queda completado el proceso de construcción de un código de Hamming.



      En el proceso de decodificación, el receptor recibe una palabra de un código de Hamming, y deberá comprobar si es correcta o no, y en el caso de que no fuera correcta deberá comprobar en que bit se produjo el error y corregir ese error.
      Para comprobar si la palabra recibida es correcta, el receptor debe utilizar los bits de paridad de la palabra y hacer con ellos un control de paridad.
      Para realizar el control de paridad creamos una palabra que tendrá un bit por cada uno de los bits de paridad utilizados. Cada uno de los bits de esta palabra tomará el valor 0 o 1 dependiendo de si el número de unos de las posiciones de la palbra de código afectadas por su correspondiente bit de paridad cumplen o no el criterio de paridad establecido. Interpretando la combinación resultante en binario natural tendremos dos posibilidades:
      - que sea un 0, lo cual quiere decir que no se han producido errores en la transmisión
      - que se corresponda a un número distinto de 0, lo cual quiere decir que durante la transmisión
      ha variado el bit situado en la posición indicada por ese número.

      Una vez obtenida la palabra de código correcta, basta con quitar los bits de paridad para obtener la palabra original enviada por el emisor.



      El siguiente applet permite al usuario interactuar para construir su propio código de Hamming y poder realizar ejemplos de decodificación y control y corrección de errores.






Códigos cíclicos

      Los códigos cíclicos son una subclase de los códigos de bloque lineales.
      Son fáciles de codificar y cumplen las siguientes propiedades:
             - Linealidad: la suma módulo-2 de dos palabras del código es otra palabra del código.
             - Cíclicos: cualquier desplazamiento cíclico de una palabra del código también pertenece
            al código.

      Al igual que en los códigos de bloque lineales sistem´ticos y en los códigos de Hamming, denotaremos un código cíclico mediante un par (n,k), donde n es la longitud de las palabras de código y k es la longitud de una palabra original.

      Para el manejo de estos códigos se utiliza una notación polinómica, de forma que una palabra de código C = (c0,......,cn-1) la interpretaremos como un polinomio, y cada uno de los bits de la palabra de código será uno de los coeficientes de este polinomio:

C(x) = c0 + c1x + . . . + cn-1xn-1

      A se vez, una palabra original m = (m0,......, mk-1) la interpretaremos como el polinomio:
m(x) = m0 + m1x + . . . + mk-1xk-1

      Para generar C(x) a partir de m(x) se usa el polinomio generador g(x) que es un factor de xn+1. Su grado es n-k. La obtención de la palabra codificada se hace de la siguiente forma:
C(x) = m(x) ·  g(x)

      Así tenemos que un código cíclico queda perfectamente determinado por su polinomio generador.
      Tal y como hemos planteado estos códigos hasta el momento, los códigos cíclicos no son sistemáticos.

      Para realizar el control de errores se utiliza el polinomio de chequeo de paridad, que es un polinomio de grado k tal que:
g(x) ·  H(x) = xn + 1




Códigos cíclicos sistemáticos

      La palabra de código de un código sistemático está formada por los bits de la palabra original y una serie de bits de paridad.
      Consideraremos la palabra de mensaje como un polinomio:

m(x) = m0 + m1x + . . . + mk-1xk-1

      A su vez consideraremos que los bits de paridad forman una palabra que también interpretaremos en forma de polinomio:
b(x) = b0 + b1x + . . . + bn-k-1xn-k-1

      Por lo tanto la palabra de código será:
C(x) = xn-km(x) + b(x)


      Teniendo en cuenta todo esto, los pasos para obtener el código cíclico sistemático son:
             1- Multiplicar la palabra original m(x) por xn-k
             2- Dividir xn-km(x) por g(x), denotando el resto por b(x). El resto es el polinomio con los
             bits de paridad
             3- La palabra codificada será:
c(x) = b(x) + xn-km(x)


      Todas las operaciones se hacen en módulo-2.


      Al igual que en los códigos de bloque lineales sistemáticos, para realizar el control de errores en la decodificación se utiliza el síndrome.
      La palabra recibida por el receptor la denotaremos por:
r(x) = r0 + r1x + . . . + rn-1xn-1

      Para calcular el síndrome utilizaremos el polinomio generador, con el cual realizaremos la siguiente división:



luego r(x) = q(x)· g(x) + S(x)

      S(x) es el polinomio de síndrome, y será de un grado n-k-1 o menor.

      El error y el síndrome coinciden, por lo tanto, si no se producen errores en la transmisión, el síndrome valdrá 0.
      Si se produce un error en los bits de paridad se puede corregir sumando el síndrome a la palabra recibida.



      El siguiente applet permite al usuario simular una transmisión utilizando este tipo de códigos:




Códigos de redundancia cíclica (CRC)

      Son un tipo de códigos cíclicos especialmente buenos para la detección de errores:

            - Se diseñan para detectar muchas combinaciones de errores.
            - La implementación práctica es sencilla. Son los que se usan en la práctica.

      Existen distintos polinomios generadores en base a pruebas:

                                                                              g(x)                                  n - k

CRC-12                          x12 + x11 + x3 + x2 + x + 1             12
CRC-16                          x16 + x15 + x2 + 1                           16
                         CRC-ITU
                               ó                                x16 + x12 + x5 + 1                           16
                         CRC-CCITT


      - Los tres contienen H(x) como factor primo
      - CRC-12 se usa con palabras de datos de 6 bits
      - CRC-16 y CRC-ITU con palabras de datos de 8 bits

      El siguiente applet permite al usuario simular una transmisión utilizando este tipo de códigos:






Códigos convolucionales

      Se diferecian de los códigos de bloque en su forma estructural y las propiedades para corregir errores.
      Los códigos de bloque suelen tener limitada la capacidad de corrección de errores alrededor de 1 o 2 símbolos erróneos por palabra de código. Estos códigos son buenos para utilizar en canales con baja probabilidad de error.
      Los códigos convolucionales son adecuados para usar sobre canales con mucho ruido (alta probabilidad de error).
      Los códigos convolucionales son códigos lineales, donde la suma de dos palabras de código cualesquiera también es una palabra de código. Y al contrario que con los códigos lineales, se prefieren los códigos no sistemáticos.
      El sistema tiene memoria: la codificación actual depende de los datos que se envían ahora y que se enviaron en el pasado.

      Un código convolucional queda especificado por tres parámetros (n,k,m):
                         n es el número de bits de la palabra codificada
                         k es el número de bits de la palabra de datos
                         m es la memoria del código o longitud restringida

Ejemplos

             - Código (2,1,3)
                          - la palabra codificada tiene 2 bits de longitud
                          - la entrada son bloques de 1 bit
                          - la salida depende de los dos bloques anteriores y del actual


             - Código (4,2,3)
                          - la palabra codificada tiene 4 bits de longitud
                          - la entrada son bloques de 2 bit
                          - la salida depende de los dos bloques anteriores y del actual





- Proceso de codificación

      El proceso de codificación de estos códigos se realiza utilizando un dispositivo lógico en el codificador.

      Ejemplo: Codificador convolucional (4,3,5)



      La palabra codificada se obtendría como el resultado de realizar una serie de operaciones lógicas entre determinados bits que están almacenados en los registros intermedios.

      Ejemplo: Codificador convolucional (2,1,3)



      - El conmutador con las dos entradas hace el papel de un registro de desplazamiento de dos
         estados.
      - El código convolucional es generado introduciendo un bit de datos y dando una revolución
         completa al conmutador.
      - Inicialmente se supone que los registros intermedios contienen ceros.

      En este ejemplo la palabra codificada se obtiene como resultado de sumas módulo-2 entre los bits indicados que están almacenados en los registros intermedios.

      Las secuencias de salida para el código anteriormente descrito:

Entrada
  (S3,S2,S1)  
Salida
    (O1,O2)    
000
00
001
11
010
01
011
10
100
10
101
01
110
11
111
00


      Como ejemplo del funcionamiento de este codificador, supongamos que se quiere enviar la secuencia de bits 0101 (donde los bits más a la derecha son los más antiguos). El proceso de codficación es el siguiente:

      - Se introduce el primer bit de la secuencia en el codificador:



      - Se introduce el segundo bit de la secuencia en el codificador:



      - Se introduce el tercer bit de la secuencia en el codificador:



      - Se introduce el cuarto bit de la secuencia en el codificador:



      Al final del proceso de codificación obtenemos que la secuencia codificada es 01 01 01 11.



      Sigamos con la exposición del proceso de codificación.

      Debido a la memoria del código es necesario de disponer de medios adecuados para determinar la salida asociada a una determinada entrada.

      Hay tres métodos gráficos:

      - Diagrama árbol o árbol del código: representación mediante un árbol binario de las
         distintas posibilidades.
      - Diagrama de estados: es la forma menos utilizada.
      - Diagrama de Trellis o enrejado: es la forma más utilizada porque es la que permite realizar
         la decodificación de la forma más sencilla.




      Para el ejemplo del codificador (2,1,3) anteriormente especificado tenemos el siguiente Arbol del código:



      La profundidad del árbol es 2· (m-1), y el número de estados es 2 (m-1) . k

      La interpretación del árbol del código es la siguiente:

            - Hay dos ramas en cada nodo.
                         - La rama superior corresponde a una entrada de un 0.
                         - La rama inferior corresponde a la entrada de un 1.
            - En la parte exterior de cada rama se muestra el valor de salida.
            - El número de ramas se va multiplicando por dos con cada nueva entrada.
            - A partir del segundo nivel el árbol se vuelve repetitivo. En realidad, solo hay cuatro tipos
               de nodos: A,B,C,D. Estos tipos de nodos en realidad son estados del codificador. A
               partir de estos nodos, se producen los mismos bits de salida y el mismo estado. Por
               ejemplo, de cualquier nodo etiquetado como C se producen el mismo par de ramas de
               salida:
                                       Salida 10 y estado A
                                       Salida 01 y estado B


      A partir de la identificación de los estados del codificador se puede incorporar esta información en el DIAGRAMA DE TRELLIS.

      El diagrama de Trellis es un diagrama en forma de red. Cada línea horizontal se corresponde con uno de los estados del codificador. Cada línea vertical se correspondería con uno de los niveles del árbol del código.
      Partimos del estado inicial del codificador en el primer nivel del árbol. A partir de aquí se trazan dos líneas desde este estado. Una para el caso de que la siguiente entrada fuera un 0 y otra para el caso de que fuera un 1. Estas líneas irán hasta el siguiente nivel del árbol al estado en el que queda el codificador después de haber codificado las correspondientes entradas. Encima de cada una de estas líneas escribiremos la salida del codificador para esa codificación.
      Para cada nivel del árbol hacemos lo mismo desde todos los estados en los que el codificador se puede encontrar.


      Según todo esto, el diagrama de Trellis para el codificador (2,1,3) de nuestro ejemplo será:



      Vamos a seguir en el diagrama de Trellis que acabamos de construir la codificación de la secuencia de bits 0101.






- Proceso de decodificación

      El proceso de decodificación consiste en buscar un camino en el diagrama de Trellis (o en el árbol del código) que nos dé la secuencia de bits más probable (si no hay errores obtendremos la secuencia exacta).
      El codificador convolucional añade una estructura a la secuencia de bits. Incluso aunque la entrada sea totalmente aleatoria, se fuerza a que la salida siga unas determinadas secuencias. Esta restricción es la que da la capacidad correctora a los códigos convolucionales.
      El procedimiento de decodificación es equivalente a comparar la secuencia recibida con todas las posibles secuencias que pueden obtenerse con el correspondiente codificador y seleccionando la secuencia que está más próxima a la secuencia recibida.

      Para realizar la decodificación se utiliza un algoritmo denominado Algoritmo de Viterbi.
      El fundamento de este algoritmo está en que no se almacenan todas las secuencias a las que da lugar el codificador.
      Se basa en el principio de optimalidad: el mejor camino (menor distancia de Hamming) a través del diagrama de Trellis que pasa por un determinado nodo, necesariamente incluye el mejor camino desde el principio del diagrama de Trellis hasta este nodo.
      El principio anterior implica que para cada uno de los nodos del diagrama de Trellis sólo es necesario guardar el mejor camino (secuencia) hasta ese nodo. De esta forma, como mucho se tendrán tantos caminos como estados diferentes (el número de estados es 2(m-1)*k).

      Descripción del algoritmo de Viterbi:

            - Paso 1: en el nivel j, calcular la distancia de Hamming de cada camino entrante en cada
               nodo (estado) desde el nodo del nivel j-1 hasta el nodo del nivel j a través del camino
              superviviente.
            - Paso 2: para cada nodo (estado) del diagrama de Trellis en el nivel j, descartar todos los
              caminos que entran en el nodo, excepto el de distancia mínima.
              Cuando a un nodo llegan dos caminos con la misma distancia se toma el superior.
            - Paso 3: pasar al nivel j+1 y repetir los pasos 1 y 2.

      Estos pasos se aplican para j mayor o igual que 2. Hasta ese valor se expanden los caminos.



      A continuación mostraremos un ejemplo de aplicación de este algoritmo sobre una cadena codificada con el codificador (2,1,3) del ejemplo de codificación.

      El codificador envía la secuencia:
                                       11 01 10 11 10 00 11
      correspondiente a la codificación de la cadena 1 0 0 1 1 1 0

      El receptor recibe la secuencia:
                                       11 01 00 11 11 00 11

      Vemos que se han producido dos errores (posiciones 5 y 10).

            Paso 1

             d(11,00) = 2 , d(11,11) = 0


            Paso 2


             2 + d(01,00) = 2 + 1 = 3 , 0 + d(01,01) = 0 + 0 = 0
             2 + d(01,11) = 2 + 1 = 3 , 0 + d(01,10) = 0 + 2 = 2

      En este momento nos encontramos en el nivel 2. A partir de ahora comenzamos a aplicar el algoritmo.
      Vemos que a cada estado del nivel 2 llega un único camino, por lo tanto nos quedamos con todos los caminos hasta el momento.


            Paso 3


             3 + d(00,00) = 3 + 0 = 3
             0 + d(00,10) = 0 + 1 = 1
             3 + d(00,11) = 3 + 2 = 5
                   . . . . . . . . . . . . . .

      Para cada estado del nivel 3 nos quedamos con el camino de menor peso que llegue a él. Los caminos que hemos seleccionado hasta el momento aparecen marcados con un color azul.


            Paso 4



            Paso 5



            Paso 6



            Paso 7



      Una vez hemos llegado al final, escogemos el camino que nos da la distancia más corta en el último nivel. Una vez seleccionado el camino, elegimos el bit que provoca la transición de estado entre dos niveles comenzando desde el primer nivel hasta el último. La secuencia de bits obtenida es la cadena decodificada.


      Para nuestro ejemplo, tenemos que la distancia más corta en el último nivel es 2 y viene dado por:



      Ahora seleccionamos en cada nivel el bit de entrada que provoca la transición de estados que se refleja según el camino obtenido.

         Nivel        
          bit           
1
1
2
0
3
0
4
1
5
1
6
1
7
0


      Por lo tanto, la secuencia decodificada obtenida es 1 0 0 1 1 1 0.
      Vemos que coincide con la cadena codificada por el codificador y enviada al decodificador. El código utilizado ha sido capaz de detectar y corregir dos errores.

      El siguiente applet permite al usuario simular una transmisión utilizando este tipo de códigos: