程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 輕松實現DES算法查看器

輕松實現DES算法查看器

編輯:關於VC++

DES(Data Encrypton Standard) 算法的實現網上已經有很多,本人在此講述 的是在DES算法加密過程中如何查看16迭代過程中生成的Ki,Li,Ri,Fi,Si等,這 樣可以當做一個DES加密對照器,這樣可以方便的發現你在加密過程中出現的錯 誤!

圖一 :程序運行界面

本程序用了一個列表框來顯示所有16次迭代的所有信息,並 在選擇一欄後,在下面的編輯框中顯示詳細信息,這樣就可以不必在列表框中拖 曳鼠標,這樣方便拷貝!
程序介紹:

采取的編程語言是微軟的VC6.0,大小為184K!實現了簡易的DES加 密查看功能!功能介紹:

1:編輯框1:輸入明文,只允許8位的ASCII碼,不允許輸入中文;

2:編輯框2:輸入密鑰,只允許8位的ASCII碼,不允許輸入中文;

3.加密按鈕:對明文加密,並在下面顯示加密後的二進制和ASCII碼;

4.對每次加密解密顯示 Ki, Li, Ri, Fi, Si的值;

5.對列表框的點擊將會詳細顯示如下信息:

Ki:加密過程中產生的子密鑰,共16個,每個48位

Li:加密過程中產生的子密鑰,共16個,每個32位

Ri:加密過程中產生的子密鑰,共16個,每個32位

Fi:加密過程中產生的子密鑰,共16個,每個32位

Si:加密過程中產生的S值,共8個,每個大小為0~15

下面就由本人詳細介紹在實現加密過程中需要注意的一些問題:

在程序一開 始的時候,我們需要在OnInitDialog這個函數內做一些初始化操作,對列表框的 操作如下,讓其顯示條形,並插入要顯示的項目:

///////////////////////////////////////////////////////////// ///////////
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加密有不對的地 方,不妨用這個試試!
可以與本人聯系:[email protected]

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved