分类: C/C++
2008-08-05 14:00:43
//////////////////////////////////////////////////////////////////////// CenterWindow(GetDesktopWindow()); ::SendMessage(m_listdata.m_hWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); m_listdata.InsertColumn(0,"NO.",LVCFMT_LEFT,30); m_listdata.InsertColumn(1,"L0",LVCFMT_LEFT,40); m_listdata.InsertColumn(2,"R0",LVCFMT_LEFT,40); m_listdata.InsertColumn(3,"F函数值",LVCFMT_LEFT,60); m_listdata.InsertColumn(4,"密钥Ki",LVCFMT_LEFT,50); m_listdata.InsertColumn(5,"S盒",LVCFMT_LEFT,45); ////////////////////////////////////////////////////////////////////////加密的过程中,需要对明文和密文检测,是否含有无法加密的字符,如中文字符,或者是否满足8位这个条件(本人并未对数据做未满8位以0补的处理):
////////////////////////////////////////////////////////////////////////// // 对输入的数据进行验证 if(m_old.GetLength()!=8) { MessageBox("请输入8位明文", "友情提示"); return; } if(m_key.GetLength()!=8) { MessageBox("请输入8位密文", "友情提示"); return; }对明文处理,将对应的ASCII码转化为二进制,并对中文字符的判断:
////////////////////////////////////////////////////////////////////////// /// 此处对明文处理,将对应的ASCII码转化为二进制 int flag=true; for(int i=0; i<8; i ) { char ch=m_old.GetAt(i); if(ch&0x80&&flag) { MessageBox("含有中文字符,加密错误不负责任!", "友情提示"); flag=false; //return; } memset(tmp, 0, 8); for(int j=0; j<8; j ) { tmp[j]=(ch%2 2)%2; ch/=2; } for(j=7; j>=0; j--) { old[i*8 7-j]=tmp[j]; } }为了实现加密解密迭代算法的共享,本人做了如下处理:
/// 此处开始16迭代算法 isDecrypt=false; for(i=1; i<=16; i ) { CDESDlg::Iterate(i); }在16次迭代算法中,大部分操作是重复的,所以采取了上述的做法!在这里,本人把迭代算法的代码全部写在这里:
void CDESDlg::Iterate(int numOfIteration) { ////////////////////////////////////////////////////////////////////////// /// 此处迭代生成子密钥ki int j=2; // 移位次数 if( numOfIteration==1||numOfIteration==2|| numOfIteration==9||numOfIteration==16) { j=1; } ////////////////////////////////////////////////////////////////////////// //如果为解密,迭代移位的次序变换相反方向 if(isDecrypt) { if(numOfIteration==16) { j=0; } else if(numOfIteration==15||numOfIteration==8||numOfIteration==1) { j=-1; } else { j=-2; } } // 省略此部分代码....... // 生成子密钥Ki,存储到数组k1[48]中去 ////////////////////////////////////////////////////////////////////////// // 将Ri-1扩充成48位并与Ki相加并模2 memset(re, 0, 48); for(i=0; i<48; i ) { re[i]=(R0[E_Table[i]-1] k1[i])%2; } ////////////////////////////////////////////////////////////////////////// // 分成8组, 每组6位,有一个二维数组s[8][6]存储 for(i=0; i<6; i ) { for(int j=0; j<8; j ) { s[j][i]=re[6*j i]; } } ////////////////////////////////////////////////////////////////////////// // 以下通过8个S盒得到8个S数并存到S[8]中S_Box[8][4][16] memset(s0, 0, 8); for(i=0; i<8; i ) { s0[i]=S_Box[i][s[i][5] s[i][0]*2][s[i][1]*8 s[i][2]*4 s[i][3]*2 s[i][4]]; } memset(stmp, 0, 8); memcpy(stmp, s0, sizeof(s0)); ////////////////////////////////////////////////////////////////////////// // 将8个数分别转换成2进制,再存入到frk[32] int f[32]; memset(f, 0, 32); for(i=0; i<8; i ) { int tmp[4]; memset(tmp, 0, 4); for(int j=0; j<4; j ) { tmp[j]=s0[i]%2; s0[i]/=2; } for(j=0; j<4; j ) { f[4*i j]=tmp[3-j]; } } // 经过P变换存入frk[32] for(i=0; i<32; i ) { frk[i]=f[P_Table[i]-1]; } int Ltmp[32], Rtmp[32]; memset(Ltmp, 0, 32); memset(Rtmp, 0, 32); for(i=0; i<32; i ) { Ltmp[i]=R0[i]; Rtmp[i]=(L0[i] frk[i])%2; } // 最后将数据存入L0,RO里面去 for(i=0; i<32; i ) { L0[i]=Ltmp[i]; R0[i]=Rtmp[i]; } CDESDlg::SaveToList(); ////////////////////////////////////////////////////////////////////////// // 16次迭代算法结束,真累呀^_^ }将数据存储到列表框是由函数CDESDlg::SaveToList()来实现的,这其实并不难,只要每次你将数据插入到列表框中就可以啦,可以看到如下:
void CDESDlg::SaveToList() { ////////////////////////////////////////////////////////////////////////// // 测试数据,将L, R, K, F, S数据存入列表 CString str, strl, strr, strs, strf, strk; str="", strl="", strr="", strk="", strs="", strf=""; item=m_listdata.InsertItem(0xffff, "N", 1); str.Format("%d", item 1); m_listdata.SetItem(item, 0, 1, str, NULL, 0, 0, 0); // 上面将第第一列的值插入,显示为迭代次数 for(int k=0; k<32; k ) { str.Format("%d", L0[k]); strl =str; str.Format("%d", R0[k]); strr =str; } for( k=0; k<32; k ) { str.Format("%d", frk[k]); strf =str; } for( k=0; k<48; k ) { str.Format("%d", k1[k]); strk =str; } for( k=0; k<8; k ) { str.Format("%d_", stmp[k]); strs =str; } m_listdata.SetItem(item, 1, 1, strl, NULL, 0, 0, 0); m_listdata.SetItem(item, 2, 1, strr, NULL, 0, 0, 0); m_listdata.SetItem(item, 3, 1, strf, NULL, 0, 0, 0); m_listdata.SetItem(item, 4, 1, strk, NULL, 0, 0, 0); m_listdata.SetItem(item, 5, 1, strs, NULL, 0, 0, 0); }在插入数据的过程中,一定要核对数据,犹其是在DES加密过程中一些数据发生了变化,更需要提前保存下来! 显示数据部分,鼠标点击显示相应的数据:
void CDESDlg::OnItemchangedList1(NMHDR* pNMHDR, LRESULT* pResult) { NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; // TODO: Add your control notification handler code here int m_nCurrentSel = pNMListView->iItem; CString info; info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,1)); GetDlgItem(IDC_EDIT7)->SetWindowText(info); info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,2)); GetDlgItem(IDC_EDIT8)->SetWindowText(info); info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,3)); GetDlgItem(IDC_EDIT9)->SetWindowText(info); info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,4)); GetDlgItem(IDC_EDIT10)->SetWindowText(info); info.Format("%s", m_listdata.GetItemText(m_nCurrentSel,5)); GetDlgItem(IDC_EDIT11)->SetWindowText(info); *pResult = 0; }就这样轻松实现了一个对8位字符进行DES加密的算法查看器!如果你在仍对DES存在疑惑的话,你可以查阅本人写的代码,如果你DES加密有不对的地方,不妨用这个试试!