⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 finalprojectcommented.c

📁 Schifra Reed-Solomon Error Correcting Code Library http://www.schifra.com Copyright (c) 2000-2007
💻 C
📖 第 1 页 / 共 2 页
字号:
void DecoderBCH(){	char i, j;	char k=0;	char delta[7];	char Syndromes[32]; 	//Lambda is an array of 7 GF32 polynomials structs	//Note: Lambda/T arrays can be small (i.e length 4) if rewrite multiply/divide, etc.	struct Poly32 lambda[7];	struct Poly32 T[7];	struct Poly32 temp;	GF32Init(Syndromes);	// Create Syndrome Polynomial	for (i=0; i<2*t; i++)		Syndromes[i+1] = (char)GF32Evaluate(i+1, EncMsgArray);	if (display_toggle & detail_toggle)	{			printf("\nSyndromes:\r\n");		GF32PrintArray(Syndromes);	}		  	/* 1  - Initialization */   	// add 1 to S(x) and initialize Berlekamp's Algorithm	Syndromes[0] = 0;	//Init Lambda[i] polynomials	for (i=0; i<7; i++)		for (j=0; j<32; j++)		{			lambda[i].p[j]=ZERO;			T[i].p[j]=ZERO;		}	// lambda_0 (x) = 1	lambda[0].p[0] = 0;    	// T_0 (x) = 1    	T[0].p[0] = 0;		while( k < t )	{      /* Berlekamp Algorithm */	  /* 2 */    // Delta[2k] = coeff. of x^(2k+1) in the product Lambda[2k](x) * [1 + Syn(x)]			 GF32Multiply(lambda[2*k].p, Syndromes, &temp);			 delta[2*k]  = (char)temp.p[2*k+1];			   	  /* 3 */ 	 // Lambda[2k+2](x) = Lambda[2k](x) + Delta[2k]*(x*T[2k](x))			 multiplyX(1, T[2*k].p, &temp);			 multiplyConstant(delta[2*k], temp.p, &temp);			 GF32Add(lambda[2*k].p, temp.p, &lambda[2*k+2]);          	  /* 4 */     			 if (delta[2*k] == ZERO || (char)GF32FindDegree(lambda[2*k].p) > k)				multiplyX(2, T[2*k].p, &T[2*k+2]);			 else			 {				multiplyX(1, lambda[2*k].p, &temp);				multiplyConstant((char)(31-delta[2*k]), temp.p, &T[2*k+2]);			 }			 if (display_toggle & detail_toggle)			 {		 	 	printf("\nDelta2k: %d\r\n",delta[2*k]);			 	printf("\nLambda2k+2:\r\n");			 	GF32PrintArray(lambda[2*k+2].p);			 	printf("\nT2k+2:\r\n");			 	GF32PrintArray(T[2*k+2].p);			  }			 	  /* 5 */     k++; // Increment for next iteration        }		  CorrectErrors(lambda[2*k].p);	// Correct the errors as determined by the locator}							// Lambda polynomial//** Concatenate **//// Concatenates two 8bit numbers into a 16bit message// Since it's a (31,16) codeunsigned long Concate(unsigned char num1, unsigned char num2){	unsigned long temp=0;		temp = temp | num1;	// Or in the num1 and shift it up	temp = temp << 8; 	temp = temp | num2;	// Or in num2		return temp;}//** Find Degree of a Polynomial in GF2 **//// Simply finds the first index of a 32bit number that is not zero// And that is the degree+1 of the polynomialunsigned char GF2FindDegree(unsigned long num){	char i=0;		num = num << 1;	// Shift left since top bit is ignored in algorithm	for(i=0; i<30; i++)	{		if (num & 0x80000000)	// Mask the current top bit, to see if it's a one			return (30-i);	// if so, that's the degree		num = num << 1;		// otherwise, keep shifting	}}//** Polynomial Addition in GF2 **//// Simply executes Modulo 2 additionunsigned long GF2Add(unsigned long a, unsigned long b){        return (a^b);	// simply xor the bits (GF2 addition for polynomials)}//** Polynomial Multiplication in GF2 **//// Executes Multiplication in GF2 for polynomialsunsigned long GF2Multiply(unsigned long a, unsigned long b){    unsigned long mul = 0;    unsigned long add;        	char i;		add = b;		 	for(i=0; i <= GF2FindDegree(a); i++) // loop while not to the end of the poly	{		if(getBit(a, i) == 1)		// If coeff. is a one, then add multiplicand			mul ^= add;		add = add<<1;			// and shift the multiplicand up one  	}    return mul;}//** Polynomial Long Division in GF2 **//// Executes Long Division in GF2 for polynomials// The remainder (qr[1]) is equal to the final dividend (qr[0])// Degree of qr[1] should be smaller than degree of divisor (the break condition in the loop)void GF2Divide(unsigned long a, unsigned long b, unsigned long *qr){	unsigned long dividend;	unsigned long divisor;	unsigned long q; 	int deg = 0;	dividend = a;	divisor = b;	qr[0] = 0;			while(1)	// Keep doing this until break is activated	{		// Subtract degrees to find what the degree of each term in the quotient		deg = (int)(GF2FindDegree(dividend) - (int)GF2FindDegree(divisor));		if (deg < 0) 	// If negative, then you are done		{			qr[1] = dividend;		// return the dividend as the remainder			return ;		}		if (deg > 0)	// otherwise find the appropriate degree for the term			q = (unsigned long)pow((float)2,(float)deg)+1;		else			q = 1;		qr[0] = GF2Add(qr[0], q);	// and add the term to the quotient		// finally, reduce (i.e add mod 2) the divided by (term*divisor)		dividend = GF2Add(dividend, (GF2Multiply(q, divisor)));	}	qr[1] = dividend;		// Return the remainder}//** Polynomial Modulo in GF2 **//// Simply executes GF2Divide to find remainder of two polynomialsunsigned long GF2Mod(unsigned long a, unsigned long b){	unsigned long qr[2] = {0,0};	GF2Divide(a, b, &qr[0]);	return qr[1];}//** Get a bit from a Long **//// Returns the bit i of the long runsigned char getBit(unsigned long r, char i){        unsigned char ret;	  	  // Shifts and Masks to get the appropriate bit        ret = ((r<<(32-i-1))>>31)& 0x00000001;        return ret;}//** Long to Array convertor **//// Takes a polynomial in GF2 (long) and coverts it into a polynomial in// GF32 (a byte array)void Bits2Bytes(unsigned long num, char *p){	char i=0, temp=0;	 	for(i=0; i<32; i++)	{		temp = num % 2;		if (temp == 0)			p[i] = ZERO;	// -1 is ZERO, i.e. coeff = 0		else			p[i] = 0;		// alpha**0, i.e. coeff = 1		num = num >> 1;		// shift for next iteration	}} //** GF32 Initialize **//// Simply initializes a GF32 array to all ZERO'svoid GF32Init(char *p){	 char i=0;	 	 for (i=0; i<32; i++)		 p[i]=ZERO;}//** GF32 Initialize **//// Prints a 32-element arrayvoid PrintArray(char *p){	char i=0;		for(i=0; i<32; i++)	{		if (i%8 == 0) printf("  ");	// Space every 8 elements for clarity		if (p[31-i] == ZERO)	// i.e. if ZERO, print 0			printf("%d ", 0);		else			printf("%d ", 1);	// otherwise it's a one	}	printf("\r\n");}//** GF32 Polynomial Print **//// Prints a 32-element array as a formatted GF32 polynomialvoid GF32PrintArray(char *p){	char i=0;	char alpha=224;	// Ascii definition for alpha		for(i=0; i<32; i++)	{		if (p[31-i] != ZERO)	// I.e. print as polynomial with coeff. in GF32			printf("%c^%d*x^%d + ", alpha, p[31-i], 31-i);	// 0 is alpha**0 = 1	}										// -1 is coeff = ZERO	printf("0\r\n"); // to make the last '+' term be sensical}//** Add Two Alpha Coeff. in GF32 **//// Uses the precomputed lookup tables to add powers of alpha mod 32char GF32add2alpha(char a, char b) {        if ((a == ZERO) && (b == ZERO))	// ZERO+ZERO=ZERO            return ZERO;        if (a == ZERO)				// ZERO is additive identity            return b;        else if (b == ZERO)            return a;        else					// Simply XOR and use lookup            return reverseLookup[lookup[a]^lookup[b]];} //** Find Degree of GF32 Polynomial **//// Returns the index of the first non-ZERO elementchar GF32FindDegree(char *p){        char i = 32;        while(--i > 0)            if (p[i] != ZERO) return i;        return 0;}//** GF32 Polynomial Evaluation **//// Evaluates the result of a polynomial defined over GF32 evaluated// with an element from GF32char GF32Evaluate(char a, char *p){	char ret = ZERO, i=0;	char pow=0;      for(i=0; i <= GF32FindDegree(p); i++) // evaluate over the length of the polynomial	{          if (p[i] != ZERO)	    {                pow = (char)((p[i]+a*i) % 31); // index is the degree, multiply exponents                if (pow < 0)                	pow = (char)(31+pow); // Evaluate mod 32                ret = GF32add2alpha(ret, pow);	// exponent multiplication = add            }        }        return ret; } //** GF32 Add Two Polynomials **//// Adds two GF32 polys using the lookup tables for each pairwise coeff.void GF32Add(char *a, char *b, struct Poly32 *powers){	char i=0;        for (i=0; i < 32; i++)            powers->p[i] = GF32add2alpha(b[i], a[i]);}//** GF32 Polynomial Multiplication **//// Multiplies two GF32 polynomials and returns the result by reference.void GF32Multiply(char *a, char *b, struct Poly32 *mul){	struct Poly32 add;	char i,j;		for(i=0; i<32; i++)	// Initialize the arrays	{		mul->p[i]=ZERO;		add.p[i]=ZERO;	}      for(i=0; i <= GF32FindDegree(a); i++)	{          if(a[i] != ZERO )	// multiply only non-zero terms	    {            for(j=0; j <= GF32FindDegree(b); j++) // add then shift		{                    if(b[j] != ZERO)                        add.p[j+i] = (char)((a[i]+b[j]) % 31);            }            GF32Add(mul->p, add.p, mul);            GF32Init(add.p);          }      }}//** Multiply GF32 Polynomial by x^power **//// Simply executes a cyclic shift (mod 32) by the power of xvoid multiplyX(char x_power, char *p, struct Poly32 *ret){	char i;        for(i=0; i<32; i++)            ret->p[(i+x_power) % 32] = p[i];	// cyclic shift mod 32} //** Multiply GF32 Polynomial by Constant **//// Simply multiplies each coeff. by an element from GF32, mod 32void multiplyConstant(char c, char *p, struct Poly32 *ret){	 char i;	       // if multiplying by zero, return zero      if(c == ZERO)	{			GF32Init(ret->p);		return ;	}      for (i = 0; i < 32; i++)	{            if(p[i] != ZERO )                ret->p[i] = (char)((p[i]+c) % 31); // add the constant exponent, mod 32            else                ret->p[i] = ZERO;      }}//** Correct the Errors in the Encoded Message **//// Corrects the encoded message according to the errors detected by the locator// polynomial, Lambda which is passed as p - i.e. the roots of Lambda// are the locations of the errorsvoid CorrectErrors(char *p){	char i;	// evaluate roots of lambda[2*k] and flip the received code word bits accordingly	for(i=0; i<32; i++)	{     		if (GF32Evaluate(i, p) == ZERO )	// Find the roots of Lambda	  	{       		if (display_toggle)	       		printf("\r\nError at index: %d\r\n", (31-i));         		if (EncMsgArray[31-i] == ZERO)	// Simply flip the bits         			EncMsgArray[31-i] = (char)0;         		else         			EncMsgArray[31-i] = ZERO;     		}   	}}//** Convert GF32 polynomial (array) to a GF2 polynomial (long) **//// Simply Or-in the appropriate bits, and shift upunsigned long Bytes2Bits(char *p){	char i;	unsigned long ret=0;		for(i=0; i<31; i++)	{		ret = ret | (p[31-i] == 0); // if 0, or in a 1, if ZERO, or in a 0		ret = ret << 1;	// and then shift it up	}	ret = ret | (p[0] == 0);	// shift up the last one - since only 31 elements		return ret;}//** De-Concatenate **//// Returns the bottom 16 bits of a long as 2 charsvoid deConcate(unsigned long a, unsigned char *ret){	a = a << 1;	ret[0] = (unsigned char)((a & 0xFF000000) >> 24);	ret[1] = (unsigned char)((a & 0x00FF0000) >> 16);}//** User Help menu **//// Displays help menu options for User, while taking into// account the appropriate status togglesvoid HelpMenu(){	printf("\r\n\n-=- Help Menu -=-\r\n\n");	if (Add_Error)		printf("--Noise Module is ON: Seed %d\r\n", seed);	if (display_toggle & detail_toggle)		printf("--Detailed Display is ON\r\n");	if (display_toggle)		printf("--Display is ON\r\n\n");	else		printf("\n");	printf("(O)utput Original Message to the Screen.\r\n");	printf("(R)un Encode/Decode and Display.\r\n");	printf("(G)eneral Display - Toggle On/Off.\r\n");	printf("(N)oise Module - Toggle On/Off.\r\n");		printf("(D)etailed Display of Intermediate Steps - Toggle On/Off.\r\n");	printf("(?)Display Help Menu.\r\n\n");}//** Get Command Initialize **//// Initializes the UART for recieving a command from the uservoid get_cmd_init(){	char_count = 0;	char_ready = 0;	UCSRB.7 = 1;	cmd_ready = 0;}//** Print a long as 4 chars **//// For use with Hyperterm, since it cannot display longsvoid PrintLong(unsigned long a){	unsigned char b,c,d,e;	b = (unsigned char)((a & 0xFF000000) >> 24)+50;	c = (unsigned char)((a & 0x00FF0000) >> 16)+50;	d = (unsigned char)((a & 0x0000FF00) >> 8)+50;		e = (unsigned char)((a & 0x000000FF))+50;	printf("%c%c%c%c\r\n",b,c,d,e);}//** Random Noise Module **//// Generates a random number of errors in random locations in the // encoded message. Essentially simulates a variably noisy channel over// which the encoded message would be transmitted.void ErrorModule(char *p, char numerrors){	char i, val;	for (i=1; i<=numerrors; i++)	// NumErrors is random and seeded by the user	{		val = (int)(rand() * (32.0) / (RAND_MAX + 1.0)) + 1; 	//random integer in 1-32 range		if (display_toggle)			printf("%d ", val-1);		if (p[val-1] == ZERO)	// Flip the appropriate bits			p[val-1] = 0;		else			p[val-1] = ZERO;	}}//** UART Recieve Interrupt **//// Captures the serial keyboard input from the user via the UARTinterrupt[USART_RXC] void UARTReceive(){	char c;	c = UDR;	UDR = c;	if(c != '\r')		cmd_str[char_count++] = c;	else	{		putchar('\n');		cmd_str[char_count] = 0;		cmd_ready = 1;		UCSRB.7 = 0;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -