S-DES算法的实现

S-DES算法的实现

 

介绍

加密算法涉及五个函数:                                                  

(1) 初始置换IP (initial permutation)

(2) 复合函数fk1,它是由子密钥K1确定的,混合了代换和置换的运算。

     (3) 交换函数SW (Switch)

     (4) 复合函数fk2 ,由子密钥K2确定

     (5) 初始置换IP的逆置换IP-1

 

加密算法的数学表示:  IP-1*fk2*SW*fk1*IP

也可写为   密文=IP-1(fk2(SW(fk1(IP(明文)))))                                                其中       K1=P8(移位(P10(密钥K)))                                                                  
           K2=P8(移位(移位(P10(密钥K))))

解密算法的数学表示:  明文=IP-1(fk1(SW(fk2(IP(密文)))))

以下是用C++写的源码

 

#include <iostream>

#include <bitset>

#include <string>

 

using namespace std;

 

const int KEY = 10;                                //密钥长度

const int HALF_KEY = 5;                        //密钥长度的一半

const int SUB_KEY = 8;                         //子密钥长度

const int TEXT = 8;                                //明文或密文的长度

const int HALF_TEXT = 4;                       //明文或密文长度的一半

const int QUARTER_TEXT = 2;                    //明文或密文长度的四分之一

 

const string P10 = "2416390875";          //置换密钥的字符串

const string P8 = "52637498";                  //从位的密钥中抽取位组成子密钥的置换字符串

const string IP = "15203746";                  //置换明文的字符串

const string IP_1 = "30246175";                //逆置换明文的字符串

const string EP = "30121230";                  //扩展置换的字符串

const int S0[4][4] =                           //S0 Box

{

     {1, 0, 3, 2},     

     {3, 2, 1, 0},

     {0, 2, 1, 3},

     {3, 1, 3, 2}

};

 

const int S1[4][4] =                           //S1 Box

{

     {0, 1, 2, 3},

     {2, 0, 1, 3},

     {3, 0, 1, 0},

     {2, 1, 0, 3}

};

 

 

class SDES

{

public:

     //构造函数

     SDES(const char* password)

     {

         key = bitset<KEY>(password);    

         k1 = CreateK1(key);

         k2 = CreateK2(key);

     }

 

     SDES(string password)

     {

         key = bitset<KEY>(password);    

         k1 = CreateK1(key);

         k2 = CreateK2(key);

     }

    

     //加密

     bitset<TEXT> Encrypt(bitset<TEXT> src)

     {

         bitset<TEXT> ipText = ExchangeTextPos(src, IP);

         bitset<HALF_TEXT> leftText = GetTextLeft(ipText);

         bitset<HALF_TEXT> rightText = GetTextRight(ipText);

         bitset<HALF_TEXT> boxOutput, rsOutput;

         boxOutput = EncryptBox(leftText, rightText, k1);

         rsOutput = EncryptBox(rightText, boxOutput, k2);

         bitset<TEXT> ip_1Text = FormText(rsOutput, boxOutput); 

         return ExchangeTextPos(ip_1Text, IP_1);

    

     }

 

     //加密

     bitset<TEXT> Encrypt(string src)

     {

         return Encrypt(bitset<TEXT>(src));

     }

    

     //解密

     bitset<TEXT> Decrypt(bitset<TEXT> src)

     {

         bitset<TEXT> ipText = ExchangeTextPos(src, IP);

         bitset<HALF_TEXT> leftText = GetTextLeft(ipText);

         bitset<HALF_TEXT> rightText = GetTextRight(ipText);

         bitset<HALF_TEXT> boxOutput, rsOutput;

         boxOutput = EncryptBox(leftText, rightText, k2);

         rsOutput = EncryptBox(rightText, boxOutput, k1);

         bitset<TEXT> ip_1Text = FormText(rsOutput, boxOutput);

         return ExchangeTextPos(ip_1Text, IP_1);

     }

 

     //解密

     bitset<TEXT> Decrypt(string src)

     {

         return Decrypt(bitset<TEXT>(src));

     }

    

private:

     bitset<KEY> key;            //密钥

     bitset<SUB_KEY> k1;              //子密钥K1

     bitset<SUB_KEY> k2;              //子密钥K2

    

     //根据参数newPos改变密钥各位的位置

     bitset<KEY> ExchangeKeyPos(bitset<KEY> src, string newPos)

     {

         bitset<KEY> rs;

         int i;

         for (i = 0; i < KEY; i++)

         {

              rs.at(KEY - 1 - i) = src.at(KEY -1 - newPos[i] + '0');

         }

         return rs;

     }

    

     //根据参数newPos改变明文各位的位置

     bitset<TEXT> ExchangeTextPos(bitset<TEXT> src, string newPos)

     {

         bitset<TEXT> rs;

         int i;

         for (i = 0; i < TEXT; i++)

         {

              rs.at(TEXT - 1 - i) = src.at(TEXT -1 - newPos[i] + '0');

         }

         return rs;

     }

    

     //获取密钥的左半边

     bitset<HALF_KEY> GetKeyLeft(bitset<KEY> src)

     {

         bitset<HALF_KEY> leftKey;

         int i;

         for (i = 0; i < HALF_KEY; i++)

         {

              leftKey.at(i) = src.at(HALF_KEY + i);

         }

         return leftKey;

     }

    

     //获取密钥的右半边

     bitset<HALF_KEY> GetKeyRight(bitset<KEY> src)

     {

         bitset<HALF_KEY> rightKey;

         int i;

         for (i = HALF_KEY; i < KEY; i++)

         {

              rightKey.at(i - HALF_KEY) = src.at(i - HALF_KEY);

         }

         return rightKey;

     }

    

     //根据密钥的左右两边形成完整的密钥

     bitset<KEY> FormKey(bitset<HALF_KEY> leftKey, bitset<HALF_KEY> rightKey)

     {

         bitset<KEY> rsKey;

         int i;

         for (i = 0; i < HALF_KEY; i++)

         {

              rsKey.at(i) = rightKey.at(i);

         }

         for (i = HALF_KEY; i < KEY; i++)

         {

              rsKey.at(i) = leftKey.at(i - HALF_KEY);

         }

         return rsKey;

     }

    

     //获取明文的左半边

     bitset<HALF_TEXT> GetTextLeft(bitset<TEXT> src)

     {

         bitset<HALF_TEXT> leftText;

         int i;

         for (i = 0; i < HALF_TEXT; i++)

         {

              leftText.at(i) = src.at(HALF_TEXT + i);

         }

         return leftText;

     }

    

     //获取明文的右半边

     bitset<HALF_TEXT> GetTextRight(bitset<TEXT> src)

     {

         bitset<HALF_TEXT> rightText;

         int i;

         for (i = HALF_TEXT; i < TEXT; i++)

         {

              rightText.at(i - HALF_TEXT) = src.at(i - HALF_TEXT);

         }

         return rightText;

     }

    

     //根据明文的左右两边形成完整的明文

     bitset<TEXT> FormText(bitset<HALF_TEXT> leftText, bitset<HALF_TEXT> rightText)

     {

         bitset<TEXT> rsText;

         int i;

         for (i = 0; i < HALF_TEXT; i++)

         {

              rsText.at(i) = rightText.at(i);

         }

         for (i = HALF_TEXT; i < TEXT; i++)

         {

              rsText.at(i) = leftText.at(i - HALF_TEXT);

         }

         return rsText;

     }

    

     //根据参数newPos从位的密钥中抽取位组成子密钥

     bitset<SUB_KEY> PickSubKey(bitset<KEY> src,string newPos)

     {

         bitset<SUB_KEY> rs;

         int i;

         for (i = 0; i < SUB_KEY; i++)

         {

              rs.at(SUB_KEY -1 -i) = src.at(KEY -1 - newPos[i] + '0');

         }

         return rs;

     }

    

     //根据参数newPos将位明文数据扩展成位

     bitset<TEXT> ExtendText(bitset<HALF_TEXT> src, string newPos)

     {

         bitset<TEXT> rs;

         int i;

         for (i = 0; i < TEXT; i++)

         {

              rs.at(TEXT - 1 - i) = src.at(HALF_TEXT -1 - newPos[i] + '0');

         }

         return rs;

     }

    

     //将一半长的密钥循环左移(有效范围~HALF_KEY位)

     bitset<HALF_KEY> CircleMoveLeft(bitset<HALF_KEY> src, int moveStep)

     {

         bitset<HALF_KEY> tmp1,tmp2,rs;

         tmp1 = src << moveStep;

         tmp2 = src >> HALF_KEY - moveStep;

         rs = tmp1 | tmp2;

         return rs;

     }

    

     //创建子密钥

     bitset<SUB_KEY> CreateSubKey(bitset<KEY> src, int moveLeft)

     {

         bitset<KEY> p10Key = ExchangeKeyPos(src, P10);

         //将密钥拆分成两半

         bitset<HALF_KEY> hKey1, hKey2;

         hKey1 = GetKeyLeft(p10Key);

         hKey2 = GetKeyRight(p10Key);

         //循环左移

         hKey1 = CircleMoveLeft(hKey1, moveLeft);

         hKey2 = CircleMoveLeft(hKey2, moveLeft);

         //将已拆成的两半重新组合成密钥

         bitset<KEY> tmpKey = FormKey(hKey1,hKey2);

         //从位的密钥中抽取位组成子密钥

         return PickSubKey(tmpKey, P8);

     }

    

     //创建子密钥K1

     bitset<SUB_KEY> CreateK1(bitset<KEY> src)

     {

         return CreateSubKey(src, 1);

     }

    

     //创建子密钥K2

     bitset<SUB_KEY> CreateK2(bitset<KEY> src)

     {

         //由于K2是在K1循环左移位的基础上循环左移位,因此总共循环左移位

         return CreateSubKey(src, 3);

     }

    

     //返回二进制数据的十进制形式(有效位数位)

     int ReturnDecimal(string binary)

     {

         if (binary == "11")

         {

              return 3;

         }

         else if (binary == "10")

         {

              return 2;

         }

         else if (binary == "01")

         {

              return 1;

         }

         else if (binary == "00")

         {

              return 0;

         }

         else

         {

              return -1;

         }

     }

    

     //SBox

     bitset<QUARTER_TEXT> SBox(bitset<HALF_TEXT> src, const int sbox[4][4])

     {

         string row = "00", col = "00";

         row[0] = src[3] + '0';

         row[1] = src[0] + '0';

         col[0] = src[2] + '0';

         col[1] = src[1] + '0';

         int decimal = sbox[ReturnDecimal(row)][ReturnDecimal(col)];

         return bitset<QUARTER_TEXT>(decimal);

     }

    

     //P4

     bitset<HALF_TEXT> P4(bitset<QUARTER_TEXT> src1, bitset<QUARTER_TEXT> src2)

     {

         bitset<HALF_TEXT> rs;

         rs[3] = src1[0];

         rs[2] = src2[0];

         rs[1] = src2[1];

         rs[0] = src1[1];

         return rs;

     }

    

     //一次加密

     bitset<HALF_TEXT> EncryptBox(bitset<HALF_TEXT> leftText, bitset<HALF_TEXT> rightText,

         bitset<SUB_KEY> subKey)

     {

         bitset<TEXT> epText = ExtendText(rightText, EP);

         bitset<TEXT> xorText1 = epText ^ subKey;

         bitset<HALF_TEXT> s0Input, s1Input;

         bitset<QUARTER_TEXT> s0Output, s1Output;

         s0Input = GetTextLeft(xorText1);

         s1Input = GetTextRight(xorText1);

         s0Output = SBox(s0Input, S0);

         s1Output = SBox(s1Input, S1);

         bitset<HALF_TEXT> p4 = P4(s0Output, s1Output);

         bitset<HALF_TEXT> boxOutput = p4 ^ leftText;

         return boxOutput;

     }   

    

};

 

 

int main(int argc, char *argv[])

{

     //验证输入参数并显示用法

     bool isValid=true;

     if (argc == 4)

     {

         isValid &= (strcmp(argv[1], "e")==0 || strcmp(argv[1], "d")==0

              || strcmp(argv[1], "E")==0 || strcmp(argv[1], "D")==0);

         isValid &= (strlen(argv[2])==10);

         isValid &= (strlen(argv[3])==8);

     }

     else

     {

         isValid = false;

     }

     if (isValid == false)

     {

         cout << endl;

         cout << "Usage: S-DES <E|D> <Key> <Text>" << endl ;

         cout << endl;

         return 0;

     }

 

     //加密或解密

     string key(argv[2]), text(argv[3]);

     SDES des(key);

     if (strcmp(argv[1], "e") == 0 || strcmp(argv[1], "E") ==0 )

     {

         cout << des.Encrypt(text) << endl;

     }

     else

     {

         cout << des.Decrypt(text) << endl;

     }

     return 0;

}

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值