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