天天看點

DES算法C++、QT實作(有圖形界面)

總共 7 個檔案。其中一個編譯配置檔案 (DES.pro) ;兩個類: DES_UI 、 DesCrypt ;兩個類共四個

檔案,分别為 DES_UI.h 、 DesCrypt.h 、 DES_UI.cpp 、 DesCrypt.cpp ;一個 GUI 檔案:

DES_UI.ui ;還有一個主函數 main.cpp 。

先上一張運作圖:

DES算法C++、QT實作(有圖形界面)

一個一個的上:

#ifndef DESCRYPT_H
#define DESCRYPT_H
#include <string>
#include <iostream>
#include <cstdlib>

using std::string;

class DesCrypt
{
public:
    DesCrypt();
    ~DesCrypt();
    void setKey(char *key);
    void encrypt(char *data);
    void decrypt(char *data);

private:
    static void inline hextobin(char h[16], char bit[64]); /* hex to binary */
    static void inline bintohex(char bit[64], char h[16]); /* binary to hex */
    static void inline _bytetobit(char ch, char bit[8]);   /* 1byte to 8bit */
    static void inline _bittobyte(char bit[8], char* ch); /* 8bit to char */
    static void inline _u8to64(char ch[8], char bit[64]); /* 8*8 to 64 bit */
    static void inline _64tou8(char bit[64], char ch[8]); /* 64 bit to 8*8 */
    static void inline IP_Trans(char data[64]);   /*IP transform*/
    static void inline IP_1_Trans(char data[64]); /*IP traverse transform*/
    static void inline E_Trans(char data[48]);    /* E transform */
    static void inline P_Trans(char data[32]);    /* P transform */
    static void inline S_Trans(char data[48]);    /* S box transform */
    static void inline PC_1_Trans(char key[64], char bit[56]);       /* PC_1 transform */
    static void inline PC_2_Trans(const char key[56], char bit[48]); /* PC_2 transform */
    static void inline ROL(char data[56], int time);                 /* cycle shift */
    static void inline XOR(char R[48], char L[48], int times);       /* XOR */
    static void inline SWAP(char L[32], char R[32]);  /* swap */
    void subKeys(char key[64], char subkeys[16][48]);  /* make the subkeys */
    void encrypt64bit(char data[8], char subkeys[16][48], char cipher[8]); /* encrypt a block */
    void decrypt64bit(char data[8], char subkeys[16][48], char cipher[8]); /* decrypt a block */

public:
    string endata;
    string dedata;
private:
    char *key = (char*)malloc(64);
    static const int IP[64];
    static const int IP_1[64];
    static const int E[64];
    static const int P[32];
    static const int S[8][4][16];
    static const int PC_1[56];
    static const int PC_2[56];
    static const int MOV[16];
};

#endif // DESCRYPT_H
           
#include "DesCrypt.h"
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cstdlib>
using namespace std;

DesCrypt::DesCrypt()
{
    this->endata = "";
    this->dedata = "";
}

void DesCrypt::setKey(char *key)
{
    if(strlen(key)==64){
        memcpy(this->key,key,64);
    }
    if(strlen(key)==8){
        _u8to64(key,this->key);
    }
    this->endata = "";
    this->dedata = "";
//    this->key = key;
}

DesCrypt::~DesCrypt()
{
    free(this->key);
}

const int DesCrypt::IP[64] = { 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,
                               56,48,40,32,24,16,8,0,
                               58,50,42,34,26,18,10,2,
                               60,52,44,36,28,20,12,4,
                               62,54,46,38,30,22,14,6};
const int DesCrypt::IP_1[64] = {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,
                                32,0,40,8,48,16,56,24};
const int DesCrypt::E[64] = {31, 0, 1, 2, 3, 4,
                             3, 4, 5, 6, 7, 8,
                             7, 8,9,10,11,12,
                             11,12,13,14,15,16,
                             15,16,17,18,19,20,
                             19,20,21,22,23,24,
                             23,24,25,26,27,28,
                             27,28,29,30,31, 0};
const int DesCrypt::P[32] = {15,6,19,20,28,11,27,16,
                             0,14,22,25,4,17,30,9,
                             1,7,23,13,31,26,2,8,
                             18,12,29,5,21,10,3,24};
const int DesCrypt::S[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}},
                                    /* S2 */
                                    {{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}},
                                    /* S3 */
                                    {{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}},
                                    /* S4 */
                                    {{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}},
                                    /* S5 */
                                    {{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}},
                                    /* S6 */
                                    {{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}},
                                    /* S7 */
                                    {{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}},
                                    /* S8 */
                                    {{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}}};
const int DesCrypt::PC_1[56] = {56,48,40,32,24,16,8,
                                0,57,49,41,33,25,17,
                                9,1,58,50,42,34,26,
                                18,10,2,59,51,43,35,
                                62,54,46,38,30,22,14,
                                6,61,53,45,37,29,21,
                                13,5,60,52,44,36,28,
                                20,12,4,27,19,11,3};
const int DesCrypt::PC_2[56] = {13,16,10,23,0,4,2,27,
                                14,5,20,9,22,18,11,3,
                                25,7,15,6,26,19,12,1,
                                40,51,30,36,46,54,29,39,
                                50,44,32,47,43,48,38,55,
                                33,52,45,41,49,35,28,31};
const int DesCrypt::MOV[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

void DesCrypt::hextobin(char h[16], char bit[64]) /* hex to binary */
{
    int i;
    int s(0);
    char tmp[2];
    for(i=0; i<8; i++){
        memcpy(tmp,h+(i<<1),2);
        if(isdigit(tmp[0]))  s = (s + tmp[0] - '0')<<4;
        else if((('a'<=tmp[0])&&(tmp[0]<='f'))||(('A'<=tmp[0])&&(tmp[0]<='F')))
            s = (s + tmp[0] - 'a' + 10) << 4;
        else continue; /* never goto here */

        if(isdigit(tmp[1]))  s += tmp[1] - '0';
        else if((('a'<=tmp[1])&&(tmp[1]<='f'))||(('A'<=tmp[1])&&(tmp[1]<='F')))
            s += tmp[1] - 'a' + 10;
        else continue; /* never goto here */
        _bytetobit((char)s,bit+(i<<3));
        s = 0;
    }
}

void DesCrypt::bintohex(char bit[64], char h[16]) /* binary to hex */
{
    int i,s(0);
    for(i=0; i<16; i++){
        s += ((bit[(i<<2)+0]-'0')<<3) + ((bit[(i<<2)+1]-'0')<<2) + ((bit[(i<<2)+2]-'0')<<1) + (bit[(i<<2)+3]-'0');
        sprintf(h+i,"%x",s);
        s = 0;
    }
}

void DesCrypt::_bytetobit(char ch, char bit[8])/* 1byte to 8bit */
{
    int i;
    int c = (char)ch;
    for(i=0; i<=7; i++){
        bit[7-i] = (c&0x01)+'0';
        c >>= 1;
    }
}

void DesCrypt::_bittobyte(char bit[8], char *ch) /* 8bit to 1byte */
{
    int i,c(0);
    for(i=0; i<8; i++){
        c += (*(bit+i)-'0')<<(7-i);
    }
    *ch = (char)c;
}

void DesCrypt::_u8to64(char ch[8], char bit[64])/* 8*8 to 64 bit */
{
    int i;
    for(i=0; i<8; i++){
        _bytetobit(*(ch+i),bit+(i<<3));
    }
}

void DesCrypt::_64tou8(char bit[64], char ch[8])/* 8bit to char */
{
    int i;
    for(i=0; i<8; i++){
        _bittobyte(bit+(i<<3),ch+i);
    }
}

void DesCrypt::IP_Trans(char data[64]) /* IP Trans */
{
    int i;
    char tmp[64];
    for(i = 0; i < 64; i++){
        tmp[i] = data[IP[i]];
    }
    memcpy(data,tmp,64);
}

void DesCrypt::IP_1_Trans(char data[64]) /*IP traverse Trans*/
{
    int i;
    char tmp[64];
    for(i = 0; i < 64; i++){
        tmp[i] = data[IP_1[i]];
    }
    memcpy(data,tmp,64);
}

void DesCrypt::E_Trans(char data[48]) /* E Trans */
{
    int i;
    char tmp[48];
    for(i = 0; i < 48; i++){
        tmp[i] = data[E[i]];
    }
    memcpy(data,tmp,48);
}

void DesCrypt::P_Trans(char data[32]) /* P Trans */
{
    int i;
    char tmp[32];
    for(i = 0; i < 32; i++){
        tmp[i] = data[P[i]];
    }
    memcpy(data,tmp,32);
}

void DesCrypt::S_Trans(char data[48]) /* S box Trans */
{
    int i;
    int line,row,out;
    int j(0),k(0);
    for(i=0; i<8; i++){
        j = i*6;
        k = i<<2;

        /* calculate the pos in S_BOX */
        line = ((data[j]-'0')<<1) + (data[j+5]-'0');
        row = ((data[j+1]-'0')<<3) + ((data[j+2]-'0')<<2) + ((data[j+3]-'0')<<1) + (data[j+4]-'0');

        out = S[i][line][row];
        /* to binary */
        data[k] = ((out&0X08)>>3)+'0';
        data[k+1] = ((out&0X04)>>2)+'0';
        data[k+2] = ((out&0X02)>>1)+'0';
        data[k+3] = (out&0x01)+'0';
    }
}

void DesCrypt::PC_1_Trans(char key[64], char bit[56]) /* PC_1 Trans */
{
    int i;
    for(i = 0; i < 56; i++){
        bit[i] = key[PC_1[i]];
    }
}

void DesCrypt::PC_2_Trans(const char key[56], char bit[48]) /* PC_2 Trans */
{
    int i;
    for(i = 0; i < 48; i++){
       bit[i] = key[PC_2[i]];
    }
}

void DesCrypt::ROL(char data[56], int time) /* cycle shift */
{
    char tmp[56];
    /* save the bit which mov to right */
    memcpy(tmp,data,time);
    memcpy(tmp+time,data+28,time);
    /* mov 1-28 */
    memcpy(data,data+time,28-time);
    memcpy(data+28-time,tmp,time);
    /* mov 29-56 */
    memcpy(data+28,data+28+time,28-time);
    memcpy(data+56-time,tmp+time,time);
}

void DesCrypt::XOR(char R[48], char L[48], int times) /* XOR */
{
    int i;
    for(i = 0; i < times; i++){
        R[i] = (R[i]^L[i]) + '0';
    }
}

void DesCrypt::SWAP(char L[32], char R[32]) /* swap */
{
    char tmp[32];
    memcpy(tmp,L,32);
    memcpy(L,R,32);
    memcpy(R,tmp,32);
}

void DesCrypt::subKeys(char key[64], char subKeys[16][48]) /* make the subkeys */
{
    char tmp[56];
    int i;
    PC_1_Trans(key,tmp); /* PC1 Trans */
    /*reduce 16 times*/
    for(i=0; i<16; i++){
        ROL(tmp,MOV[i]); /* mov left */
        PC_2_Trans(tmp,subKeys[i]);/* PC2 Trans to make subkeys */
    }
}

void DesCrypt::encrypt64bit(char data[8], char subKeys[16][48], char cipher[8])
{
    char plainbit[64];
    char right[48];
    int i;

    _u8to64(data,plainbit);
    IP_Trans(plainbit);
    for(i = 0; i < 16; i++){
        memcpy(right,plainbit+32,32);

        E_Trans(right);
        XOR(right,subKeys[i],48);
        S_Trans(right);
        P_Trans(right);

        XOR(plainbit,right,32);
        if(i != 15){
            SWAP(plainbit,plainbit+32);
        }
    }
    IP_1_Trans(plainbit);
    _64tou8(plainbit,cipher);
    char c[16];
    bintohex(plainbit,c);
    string str(&c[0],&c[16]);
    this->endata += str;
}

void DesCrypt::decrypt64bit(char cipher[64], char subKeys[16][48], char data[8])
{
    char cipherbit[64];
    memcpy(cipherbit,cipher,64);
    char right[48];
    int i;
    IP_Trans(cipherbit);

    for(i = 15; i >= 0; i--){
        memcpy(right,cipherbit+32,32);

        E_Trans(right);
        XOR(right,subKeys[i],48);
        S_Trans(right);
        P_Trans(right);

        XOR(cipherbit,right,32);
        if(i != 0){
            SWAP(cipherbit,cipherbit+32);
        }
    }
    IP_1_Trans(cipherbit);
    _64tou8(cipherbit,data);
    string str(&data[0],&data[8]);
    this->dedata += str;
}

void DesCrypt::encrypt(char *data)
{
    char plainBlock[8],cipher[8];
    char subk[16][48];
    char eof = '\0';
    long i(0);

    subKeys(this->key,subk);

    long len = strlen(data);
    while(len%8 != 0){
        strcat(data,&eof);
        len++;
    }
    for(i=0; i<len/8; i++){
        memcpy(plainBlock,data+(i<<3),8);
        encrypt64bit(plainBlock,subk,cipher);
    }
}

void DesCrypt::decrypt(char *data)
{
    char plainBlock[8],cipher[64],tmp[16];
    char subk[16][48];
    char eof = '\0';
    long i(0);

    subKeys(this->key,subk);
    long len = strlen(data);
    while(len%16 != 0){
        strcat(data,&eof);
        len++;
    }
    for(i=0; i<len/16; i++){
        memcpy(tmp,data+(i<<4),16);
        hextobin(tmp,cipher);
        decrypt64bit(cipher,subk,plainBlock);
    }
}
           
#ifndef DES_UI_H
#define DES_UI_H

#include <QWidget>
#include "DesCrypt.h"

namespace Ui {
class DES_UI;
}

class DES_UI : public QWidget
{
    Q_OBJECT

public:
    explicit DES_UI(QWidget *parent = 0);
    ~DES_UI();
    
private:
    Ui::DES_UI *ui;
    DesCrypt* Des = new DesCrypt();

private slots:
    void encrypt();
    void decrypt();
};

#endif // DES_UI_H
           
#include "DES_UI.h"
#include "ui_DES_UI.h"

DES_UI::DES_UI(QWidget *parent) : QWidget(parent), ui(new Ui::DES_UI)
{
    ui->setupUi(this);
    QString str = "computer";
    ui->keyline->setText(str);
    str = "learning";
    ui->en_Text->setPlainText(str);
    str = "cipher:894cb732df9de103\ndata:learning";
    ui->plainTextEdit->setPlainText(str);
    connect(ui->en_Button,SIGNAL(clicked()),this,SLOT(encrypt()));
    connect(ui->de_Button,SIGNAL(clicked()),this,SLOT(decrypt()));
}

DES_UI::~DES_UI()
{
    delete ui;
    delete Des;
}

void DES_UI::encrypt()
{
    QString Qkey = ui->keyline->text();
    QString data = ui->en_Text->toPlainText();
    ui->de_Text->clear();
    QString err = "InputError,please check your input!";
    if(Qkey.isEmpty()||data.isEmpty()){
        ui->de_Text->setPlainText(err);
        return;
    }
    if(Qkey.length()!=8){
        ui->de_Text->setPlainText("length of key must be 8!");
        return;
    }

    char *key = Qkey.toLatin1().data();
    Des->setKey(key);
    Des->encrypt(data.toLatin1().data());
    QString endata = QString::fromLocal8Bit(Des->endata.c_str());
    ui->de_Text->setPlainText(endata);
}

void DES_UI::decrypt()
{
    QString Qkey = ui->keyline->text();
    QString data = ui->de_Text->toPlainText();
    ui->en_Text->clear();
    QString err = "InputError,please check your input!";
    if(Qkey.isEmpty()||data.isEmpty()){
        ui->en_Text->setPlainText(err);
        return;
    }
    if(Qkey.length()!=8){
        ui->de_Text->setPlainText("length of key must be 8!");
        return;
    }

    char *key = Qkey.toLatin1().data();
    Des->setKey(key);
    Des->decrypt(data.toLatin1().data());
    QString dedata = QString::fromLocal8Bit(Des->dedata.c_str());
    ui->en_Text->setPlainText(dedata);
}
           
#include "DES_UI.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    DES_UI w;
    w.show();
    
    return a.exec();
}
           
#-------------------------------------------------
#
# Project created by QtCreator 2014-04-15T19:29:12
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = DES
TEMPLATE = app


SOURCES += main.cpp\
        DES_UI.cpp \
    DesCrypt.cpp

HEADERS  += DES_UI.h \
    DesCrypt.h

FORMS    += DES_UI.ui
           
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>DES_UI</class>
 <widget class="QWidget" name="DES_UI">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>658</width>
    <height>515</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>DES Crypt  V1.0</string>
  </property>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>30</y>
     <width>57</width>
     <height>15</height>
    </rect>
   </property>
   <property name="text">
    <string>KEY:</string>
   </property>
  </widget>
  <widget class="QLineEdit" name="keyline">
   <property name="geometry">
    <rect>
     <x>60</x>
     <y>20</y>
     <width>201</width>
     <height>31</height>
    </rect>
   </property>
  </widget>
  <widget class="QPlainTextEdit" name="en_Text">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>60</y>
     <width>281</width>
     <height>291</height>
    </rect>
   </property>
  </widget>
  <widget class="QPlainTextEdit" name="de_Text">
   <property name="geometry">
    <rect>
     <x>350</x>
     <y>60</y>
     <width>271</width>
     <height>291</height>
    </rect>
   </property>
  </widget>
  <widget class="QPlainTextEdit" name="plainTextEdit">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>390</y>
     <width>601</width>
     <height>111</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="en_Button">
   <property name="geometry">
    <rect>
     <x>90</x>
     <y>360</y>
     <width>87</width>
     <height>27</height>
    </rect>
   </property>
   <property name="text">
    <string>加密</string>
   </property>
  </widget>
  <widget class="QPushButton" name="de_Button">
   <property name="geometry">
    <rect>
     <x>440</x>
     <y>360</y>
     <width>87</width>
     <height>27</height>
    </rect>
   </property>
   <property name="text">
    <string>解密</string>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>
           

最後,代碼運作環境,linux,可能linux運作更多自由的格式,比如可以在頭檔案裡面配置設定内在,vc++可能不行,有些代碼需要稍稍移動或修改。

繼續閱讀