[C con Clase] CRC
Bernardo Reyes
bernardo5304 en gmail.com
Vie Ago 31 18:49:20 CEST 2007
Hola , gracias por responder , pero el algoritmo esta bien :S LA
funcion correr_izq no hace un corrimiento de bits , simplemente la uso
para eliminar los ceros del principio de la cadena. Mira , este es mi
nuevo codigo y ya sirvio , aunque tienes razon en que no deberia de
regresar una variable local. Al reservar memoria con malloc no me
marca error a pesar de que regrese una variable local ¿ porque es?
Ah y eso de agregar ficheros fuente je , pues si tienes razon debi
hacer un .h pero solo lo hice asi rapido para no tener todo en main.
Gracias .
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define MAX 31
char p[]="11000000000000101";
int n=16;
/*CRC-16: x16 + x15 + x2 + 1. Para flujos de 8 bits, con 16 de redundancia.
Usado en Estados Unidos, principalmente*/
void XOR(char *x,char *y){
int i=strlen(x)-strlen(y);
int j=0;
while(x[i]!='\0'){
if(x[i]==y[j])x[i]='0';
else x[i]='1';
i++;
j++;
}
}
void correr_izq(char *cad){
int i;
for(i=0;cad[i]!='\0';i++) cad[i]=cad[i+1];
}
/*===Quta ceros despues del XOR====*/
int quitar_ceros_izq(char *cad){
int cont=0;
while(cad[0]=='0'){
correr_izq(cad);
cont++;
}
return cont;
}
char* division(char *msj, char *p){
int long_msj=strlen(msj);
int long_p=strlen(p);
int cont=0;
int cont2=long_p; //Nos ayuda a saber hasta donde hemos dividido
int i;
int ceros;
char *res=(char*)malloc(sizeof(char)*long_msj);
char *aux2=(char*)malloc(sizeof(char)*long_p);
strncpy(aux2,msj,long_p);
aux2[long_p]='\0';
res[0]='1';
cont++;
while(cont2<=long_msj){
res[cont]='\0';
XOR(aux2,p);
ceros=quitar_ceros_izq(aux2);
int auxx=strlen(aux2);
for(i=0;i<ceros;i++,cont2++,cont++){ //Baja tantos numeros
del dividendo
aux2[auxx+i]=msj[cont2]; //como ceros hallan
quedado luego del XOR
aux2[strlen(aux2)]='\0'; //y pone en el resultado 0
res[cont]='0';
}
res[cont-1]='1'; //Al terminar de bajar los ceros , ya
se puede dividir,
//por eso ponemos 1
}
if(strlen(aux2)==0) {aux2[0]='0'; aux2[1]='\0';} //Si el ultimo
XOR da puros ceros , estos son eliminados
//y la lngitud de la cadena queda en cero, indicando que el
residuo fue cero.
return aux2;
}
/*====Convierte una letra a su representacion en binario====*/
char* DecimalBinario (unsigned char decimal)
{
int i=0,j=0,contador=0;
unsigned char array[40];
char aux[40];
char cad[49];
unsigned char resultado;
do
{
resultado=decimal%2;
decimal=decimal/2;
array[i]=resultado;
i=i+1;
contador=contador+1;
}while(decimal!=0);
for (i=contador-1,j=0;i>=0;j++,i--) //Se debe invertir la cadena
{
if(array[i]==0) aux[j]='0';
else aux[j]='1';
aux[j+1]='\0';
}
return aux;
}
void corrimiento(char*cad, int n){ //Corrimiento a la izquierda de n "bits"
//int len=strlen(cad);
int i;
//cad[len]='0';
for(i=0;i<n;i++){cad[i]='0';cad[i+1]='\0';}
}
void retardo ()
{
time_t start_time = time(NULL); //Toma la hora del sistema
while (difftime(time(NULL), start_time) < 3.0) ; //Hasta que la
diferencia entre la hora actual
//y la guardada sea 3 se rompe el ciclo
}
#include "funciones.c"
int main(){
char *residuo=(char*)malloc(sizeof(char)*strlen(p));
char *mensaje_binario;
char msj[MAX];
int i=0;
printf("Introduce la cadena : ");
fgets(msj, MAX, stdin);
mensaje_binario=(char*)malloc(sizeof(char)*strlen(msj)*8+n);
strcpy(mensaje_binario,DecimalBinario(msj[i]));
for(i=1;i<strlen(msj)-1;i++) strcat(mensaje_binario,DecimalBinario(msj[i]));
printf("\n Mensaje en binario %s",mensaje_binario);
corrimiento(&mensaje_binario[strlen(mensaje_binario)],n);
printf("\n Mensaje en binario con corrimiento: %s\n\n\n",mensaje_binario);
printf("\n CRC 16: %s", p);
residuo= division(mensaje_binario,p);
printf("\n El residuo de la division es : %s\n", residuo);
printf("\n Añadiendo bits para la deteccion de errores...");
retardo();
XOR(mensaje_binario,residuo);
printf("\n \n \n Trama a enviar: %s", mensaje_binario);
residuo= division(mensaje_binario,p);
printf("\n\n\n COMPROBANDO...\n");
retardo();
printf("\n El residuo de la division entre la trama y el polinomio es
: %s\n\n\n\n", residuo);
system("pause");
}
Ah y siempre se me olvida liberar memoria. Lo siento :-S
Hasta luego.
Más información sobre la lista de distribución Cconclase