DES 算法 C51 单片机

      顶顶大名的DES算法大家都知道吧,呵呵!这里就不用多做介绍了,关于它的c源码,网上一搜一大把,虽然很多是不正确的实现,但是也有正确的,比如:http://www.cnblogs.com/erwin/archive/2009/04/14/1435288.html这位达人的算法实现个人认为还是不错的,至少它的加密结果是正确的,而且结构相当清晰,虽然还有点小bug(可以看这篇日志下面的评论),但是胖子认为自己是写不出这么好的程序(DES太可怕啦)!如果说有童鞋怀疑其加密结果的正确性,或者想验证一下自己写的DES程序的结果是否正确,胖子在这里提供一个比较权威的工具,你到中文wiki上找到DES的介绍页面,页面下方有个链接,是一个DES的实现,当然是用的javascript,不过它限制了密钥的不能更改,你可以保存页面后,把那个textbox的属性改一下就可以验证了。只输入第一个密钥,则加密算法就是DES(http://people.eku.edu/styere/Encrypt/JS-DES.html)。

        好了,废话不多说了,该进入今天的主题了。就是C51单片机上DES算法的实现。众所周知,51单片机的ram很小,胖子用的这个ram+flash才512byte,这对于DES的实现提出了非常苛刻的要求。胖子自问没有时间搞这个,所以就求助谷歌与百度大叔,花费了n久,历经n次劫难,最终取得真经。以下就是程序源码:

 

#include <string.h>
#include <stdlib.h>
#include <reg52.h>
static unsigned char code DesIp[] =
{ 
	58, 50, 42, 34, 26, 18, 10, 2,
	60, 52, 44, 36, 28, 20, 12, 4,
	62, 54, 46, 38, 30, 22, 14, 6,
	64, 56, 48, 40, 32, 24, 16, 8,
	57, 49, 41, 33, 25, 17, 9,   1,
	59, 51, 43, 35, 27, 19, 11, 3,
	61, 53, 45, 37, 29, 21, 13, 5,
	63, 55, 47, 39, 31, 23, 15, 7
};



static unsigned char code DesIp_1[] =
{
	40, 8,  48, 16, 56, 24, 64, 32,
	39, 7,  47, 15, 55, 23, 63, 31,
	38, 6,  46, 14, 54, 22, 62, 30,
	37, 5,  45, 13, 53, 21, 61, 29,
	36, 4,  44, 12, 52, 20, 60, 28,
	35, 3,  43, 11, 51, 19, 59, 27,
	34, 2,  42, 10, 50, 18, 58, 26,
	33, 1,  41, 9,  49, 17, 57, 25
};



static unsigned char code DesS[8][4][16] = 
{
	{
		{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
		{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
		{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
		{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
	},
	
	{
		{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
		{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
		{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
		{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
	},
	
	{
		{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
		{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
		{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
		{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
	},
	
	{
		{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
		{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
		{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
		{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
	},
	
	{
		{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
		{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
		{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
		{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
	},
	
	{
		{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
		{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
		{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
		{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
	},
	
	{
		{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
		{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
		{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
		{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
	},
	
	{
		{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
		{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
		{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
		{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
	}
};



static unsigned char code DesE[] =
{
	32, 1, 2, 3, 4, 5,
	4, 5, 6, 7, 8, 9,
	8, 9, 10, 11, 12,13,
	12, 13, 14, 15, 16, 17,
	16, 17, 18, 19, 20, 21,
	20, 21, 22, 23, 24, 25,
	24, 25, 26, 27, 28, 29,
	28, 29, 30, 31, 32, 1
};



static unsigned char code DesP[] = 
{
	16, 7, 20, 21,
	29, 12, 28, 17,
	1, 15, 23, 26,
	5, 18, 31, 10,
	2, 8, 24,  14,
	32, 27, 3, 9,
	19, 13, 30, 6,
	22, 11, 4, 25
};



static unsigned char code DesPc_1[] =
{
	57, 49, 41, 33, 25, 17, 9,
	1, 58, 50, 42, 34, 26, 18,
	10, 2, 59, 51, 43, 35, 27,
	19, 11, 3, 60, 52, 44, 36,
	63, 55, 47, 39, 31, 23, 15,
	7, 62, 54, 46, 38, 30, 22,
	14, 6, 61, 53, 45, 37, 29,
	21, 13, 5, 28, 20, 12, 4
};



static unsigned char code DesPc_2[] =
{
	14, 17, 11, 24, 1, 5,
	3, 28, 15, 6, 21, 10,
	23, 19, 12, 4, 26, 8,
	16, 7, 27, 20, 13, 2,
	41, 52, 31, 37, 47, 55,
	30, 40, 51, 45, 33, 48,
	44, 49, 39, 56, 34, 53,
	46, 42, 50, 36, 29, 32
};



static unsigned char code DesRots[] = 
{
	1, 1, 2, 2, 
	2, 2, 2, 2, 
	1, 2, 2, 2, 
	2, 2, 2, 1, 
	0
};



static void movram(unsigned char* source,unsigned char* target,unsigned char length);
static void doxor(unsigned char* sourceaddr,unsigned char* targetaddr,unsigned char length);
static void setbit(unsigned char* dataddr,unsigned char pos,unsigned char b0);
static unsigned char getbit(unsigned char* dataddr,unsigned char pos);
static void selectbits(unsigned char* source,unsigned char* table,unsigned char* target,unsigned char count);
static void shlc(unsigned char* data_p);
static void shrc(unsigned char* data_p);
static void strans(unsigned char* index,unsigned char* target);


static void movram(unsigned char* source,unsigned char* target,unsigned char length)
{
	unsigned char i;
	
	for(i = 0;i < length;i++)/*?????*/
	{
		target[i] = source[i];
	}
}



static void doxor(unsigned char* sourceaddr,unsigned char* targetaddr,unsigned char length)
{
	unsigned char i;
	
	for (i = 0;i < length;i++)/*???*/
	{
		sourceaddr[i] ^= targetaddr[i];
	}
}



static void setbit(unsigned char* dataddr,unsigned char pos,unsigned char b0)	
{
	unsigned char byte_count;
	unsigned char bit_count;
	unsigned char temp;

	temp = 1;
	byte_count = (pos - 1) / 8;
	bit_count = 7 - ((pos - 1) % 8);
	temp <<= bit_count;
	
	if(b0)
	{
		dataddr[byte_count] |= temp;
	}
	else
	{
		temp = ~temp;
		dataddr[byte_count] &= temp;
	}
}



static unsigned char getbit(unsigned char* dataddr,unsigned char pos)	
{
	unsigned char byte_count;
	unsigned char bit_count;
	unsigned char temp;

	temp = 1;
	byte_count = (pos - 1) / 8;
	bit_count = 7 - ((pos - 1) % 8);
	temp <<= bit_count;
	if(dataddr[byte_count] & temp)
	{
		return(1);
	}
	else 
	{
		return(0);
	}
}



static void selectbits(unsigned char* source,unsigned char* table,unsigned char* target,unsigned char count)
{
	unsigned char i;
	
	for(i = 0;i < count;i++)
	{
		setbit(target,i + 1,getbit(source,table[i])); 
	}
}



static void shlc(unsigned char* data_p)
{
	unsigned char i,b0;
	
	b0 = getbit(data_p,1);
	
	for(i = 0;i < 7;i++)
	{
		data_p[i] <<= 1;
		
		if(i != 6)
		{
			setbit(&data_p[i],8,getbit(&data_p[i + 1],1));
		}
	}
	
	setbit(data_p,56,getbit(data_p,28));
	setbit(data_p,28,b0);
}



static void shrc(unsigned char* data_p)
{
	unsigned char b0;
	int i;
	
	b0 = getbit(data_p,56);
	
	for(i = 6;i >= 0;i--)
	{
		data_p[i] >>= 1;
		
		if(i != 0)
		{
			setbit(&data_p[i],1,getbit(&data_p[i - 1],8)); 
		}
	}
	
	setbit(data_p,1,getbit(data_p,29));
	setbit(data_p,29,b0);
}



/* The problem is about yielded in this function */
static void strans(unsigned char* index,unsigned char* target)
{
	unsigned char row,line,t,i,j,b0,b1;
	
	for(i = 0;i < 4;i++)
	{
		row = line = t = 0;
		setbit(&line,7,b0 = getbit(index,i * 12 + 1));
		setbit(&line,8,b1 = getbit(index,i * 12 + 6));
		
		for(j = 2;j < 6;j++)
		{
			setbit(&row,3 + j,getbit(index,i * 12 + j));
		}
		
		t = DesS[i * 2][line][row];
		t <<= 4;
		line = row = 0; 
		setbit(&line,7,getbit(index,i * 12 + 7));
		setbit(&line,8,getbit(index,i * 12 + 12));
		
		for(j = 2;j < 6;j++)
		{
			setbit(&row,3 + j,getbit(index,i * 12 + 6 + j));
		}
		
		t |= DesS[i * 2 + 1][line][row];
		target[i] = t;
	}
}




void des(unsigned char *data_p,unsigned char* key_p,int type)
{
	unsigned char tempbuf[12];
	unsigned char key[7];
	unsigned char i;
	unsigned char j;
	unsigned char count;
	void (*f)(unsigned char* data_p);
	
	selectbits(data_p,DesIp,tempbuf,64);/*????*/
	movram(tempbuf,data_p,8);
	selectbits(key_p,DesPc_1,key,56);/*KEY?????*/
	
	for(i = 0;i < 16;i ++)
	{
		selectbits(data_p + 4,DesE,tempbuf,48);/*????*/
		
		if(type ==1)		//jia mi
		{
			f = shlc;
			count = i;
		}
		else
		{
			count = 16 - i;	
			f = shrc;
		}
		
		for(j = 0;j < DesRots[count];j++)/*KEY ???*/
		{
			f(key);
		}
		
		selectbits(key,DesPc_2,tempbuf + 6,48);/*KEY ????*/
		doxor(tempbuf,tempbuf + 6,6);
		strans(tempbuf,tempbuf + 6);
		selectbits(tempbuf + 6,DesP,tempbuf,32);
		doxor(tempbuf,data_p,4);
		
		if(i < 15)
		{
			movram(data_p + 4,data_p,4);
			movram(tempbuf,data_p + 4,4);
		}
	}
	
	movram(tempbuf,data_p,4);
	selectbits(data_p,DesIp_1,tempbuf,64);
	movram(tempbuf,data_p,8);
}
void main(void)
{
      unsigned char key[8] = {'c','o','m','p','u','t','e','r'
      unsigned char text[8]={'l','e','a','r','n','i','n','g'};
      des(text,key,1);
      
}

          在这里胖子只能说是付出了上网和测试的功劳,至于编码的功劳不敢冒领,可惜不知道作者是谁,在这里向这位达人致敬了smiley~,在这里希望各位需要在单片机上跑DES的各位童鞋,少走点弯路,欢迎转载,当然请注明出处,哈哈~