UI.h
cpp
#include "Vigenere.h"
#include "CPC.h"
#include "DES.h"
void Surface();
void VegeSurface();
void CPCSurface();
void DESSurface();
UI.cpp
cpp
#include <iostream>
#include <conio.h>
#include "UI.h"
using namespace std;
void main()
{
Surface();
}
void Surface()
{
system("cls");
cout << "1.Vigenere Cipher"<< endl;
cout << "2.Column Permutation Cipher" << endl;
cout << "3.DES" << endl;
cout << "4.Exit" << endl << endl << endl;
char choice;
choice = getch();
switch (choice)
{
case '1':VegeSurface(); break;
case '2':CPCSurface(); break;
case '3':DESSurface(); break;
default:break;
}
}
void VegeSurface()
{
system("cls");
cout << "1.Encryption" << endl;
cout << "2.Decryption" << endl;
cout << "3.back" << endl;
char choice;
choice = getch();
switch (choice)
{
case '1':VigenereEn(); break;
case '2':VigenereDe(); break;
case '3':Surface(); break;
default:break;
}
Surface();
}
void CPCSurface()
{
system("cls");
cout << "1.Encryption" << endl;
cout << "2.Decryption" << endl;
cout << "3.back" << endl;
char choice;
choice = getch();
switch (choice)
{
case '1':CPCEn(); break;
case '2':CPCDe(); break;
case '3':Surface(); break;
default:break;
}
Surface();
}
void DESSurface()
{
system("cls");
cout << "1.Encryption" << endl;
cout << "2.Decryption" << endl;
cout << "3.back" << endl;
char choice;
choice = getch();
switch (choice)
{
case '1':DES(choice); break;
case '2':DES(choice); break;
case '3':Surface(); break;
default:break;
}
Surface();
}
DES.h
cpp
int DES(char choice);
int getText(char choice);
//char and bit
void OutputChar(char a);
void SetCharBit(char *p, int pos, int bit);
int getCharPos(char a, int pos);
void Output(char a[]);
//key
void Add8Bit();
void PC_1();
void GeneratingSubkey();
void OutputSubkey();
//encryption and decryption
int AddText(int n);
void IT(char *text, char *LP, char *RP, int e);
void EBOX(char *EOut, char *RP);
void SBOX(int stage, char *SIn, char *EOut, char *SOut);
void PBOX(char *SOut, char *POut);
void CHANGE(char *LP, char *RP, char *POut);
void FT(char *LP, char *RP, int e);
void Write2File(int n);
int DeleteQ(int len);
DES.cpp
cpp
#include "DES.h"
#include "Order.h"
#include "Common.h"
#include <windows.h>
#include <fstream>
#include <iostream>
using namespace std;
//-----------------------------------------------------------------------------------------
//text
char TotalText[9999];
char AimText[9999];
//key
char subkey[16][7];
char MasterKey[9];
char key1[8];
char key2[8];
char key[2][8];
int EN_OR_DE = 0; //a flag
//-----------------------------------------------------------------------------------------
HANDLE hKEY, hENORDE[999], hWAIT; //定义线程句柄
DWORD WINAPI KEY(LPVOID lpParameter);
DWORD WINAPI ENORDE(LPVOID lpParameter);
DWORD WINAPI WAIT(LPVOID lpParameter);
//-----------------------------------------------------------------------------------------
int DES(char choice)
{
TotalText[0] = '\0';
AimText[0] = '\0';
int i = getText(choice);
if (0 == i)
return 0;
hKEY = ::CreateThread(NULL, 0, KEY, NULL, 0, NULL); //创建key线程
int block = AddText(i) / 8 - 1;
int e[999];
AimText[(block + 1) * 8] = '\0';
hWAIT = ::CreateThread(NULL, 0, WAIT, &block, 0, NULL);
for (i = 0; i <= block; i++)
{
e[i] = i;
hENORDE[i] = ::CreateThread(NULL, 0, ENORDE, &e[i], 0, NULL);
}
while (1)
{
if (WaitForSingleObject(hWAIT, INFINITE) == WAIT_OBJECT_0) //等待加密/解密过程结束
break;
}
for (i = 0; i <= block; i++)
::CloseHandle(hENORDE[i]);
::CloseHandle(hKEY);
::CloseHandle(hWAIT);
Write2File((block + 1) * 8);
return 1;
}
//-----------------------------------------------------------------------------------------
//function about char and output
//output a char as 0s and 1s
void OutputChar(char a)
{
cout << endl;
int j = 0;
for (j = 0; j <= 7; j++)
{
cout << ((a >> (7 - j)) & 1);
}
cout << endl;
}
void SetCharBit(char *p, int pos, int bit)
{
*p = ((*p) | (~x[pos])) & ((bit << (7 - pos) | x[pos]));
}
int getCharPos(char a, int pos) //a is char, pos //
{
return ((a >> (7 - pos)) & 1);
}
//output a char[] as 0s and 1s
void Output(char a[])
{
int k = 1, i = 0, j = 0;
for (i = 0; i < strlen(a); i++)
{
for (j = 0; j <= 7; j++)
{
cout << ((a[i] >> (7 - j)) & 1);
if (0 == k % 8)
cout << endl;
k++;
}
}
cout << endl << endl;
}
//----------------------------------------------------------------------------------------
//deal with key
//key线程
DWORD WINAPI KEY(LPVOID lpParameter)
{
Add8Bit();
PC_1();
GeneratingSubkey();
//OutputSubkey();
return 0;
}
void Add8Bit()
{
//get key from keyboard
cout << "enter key ";
cin >> key1;
system("cls");
//第a位(按数组,从0开始),第b个字符(按数组,从0开始)
//flag用作奇偶校验(1的个数)
//process of 56->64
int i = 0, j = 0, flag = 0, a = 0, b = 0;
char *p;
for (i = 0; i <= 7; i++)
{
flag = 0;
p = &MasterKey[i];
for (j = 0; j <= 6; j++)
{
SetCharBit(p, j, getCharPos(key1[b], a));
if (0 == getCharPos(key1[b], a))
flag++;
a++;
if (8 == a)
{
a = 0;
b++;
}
}
SetCharBit(p, j, flag % 2);
}
/*
cout << "the 56-bit key that you enter" << endl;
Output(key1);
cout << "the 64-bit key after adding 8 additional 0s and 1s" << endl;
Output(MasterKey);
*/
}
void PC_1()
{
int i = 0, j = 0, a = 0, b = 0, k = 0;
char *p;
for (i = 0; i <= 6; i++)
{
p = &key2[i];
for (j = 0; j <= 7; j++)
{
a = Pc1Order[k] % 8; //a!=0
b = (Pc1Order[k] - a) / 8;
a--;
SetCharBit(p, j, getCharPos(MasterKey[b], a));
k++;
}
}
/*
cout << "the 56-bit key after the 64-bit key discarding 8,16,24,32,40,48,56,64" << endl;
Output(key2);
*/
}
void GeneratingSubkey()
{
//process of generating subkey
int i = 0, j = 0, shiftBit = 0, k = 0;
int a = 0, b = 0, c = 0, d = 0, u = 0;
char *p;
for (i = 0; i <= 15; i++)
subkey[i][6] = '\0';
for (i = 0; i <= 6; i++)
key[0][i] = key2[i];
for (i = 0; i <= 15; i++)
{
//cyclic left shift
if (0 == i || 1 == i || 8 == i || 15 == i)
{
shiftBit = 1;
//left part
p = &key[(i + 1) % 2][3];
SetCharBit(p, 3, getCharPos(key[i % 2][0], 0));
//right part
p = &key[(i + 1) % 2][6];
SetCharBit(p, 7, getCharPos(key[i % 2][3], 4));
}
else
{
shiftBit = 2;
//left part
p = &key[(i + 1) % 2][3];
SetCharBit(p, 2, getCharPos(key[i % 2][0], 0));
p = &key[(i + 1) % 2][3];
SetCharBit(p, 3, getCharPos(key[i % 2][0], 1));
//right part
p = &key[(i + 1) % 2][6];
SetCharBit(p, 7, getCharPos(key[i % 2][3], 5));
p = &key[(i + 1) % 2][6];
SetCharBit(p, 6, getCharPos(key[i % 2][3], 4));
}
for (j = 0; j <= 55 - shiftBit; j++)
{
a = j % 8;
b = (j - a) / 8;
c = a + shiftBit;
d = b;
if (8 == c || 9 == c)
{
c = c - 8;
d++;
}
SetCharBit(&key[(i + 1) % 2][b], a, getCharPos(key[i % 2][d], c));
if (27 - shiftBit == j)
j = 27;
}
//PC_2
k = 0;
for (u = 0; u <= 5; u++)
{
p = &subkey[i][u];
for (j = 0; j <= 7; j++)
{
a = (Pc2Order[k] - 1) % 8;
b = (Pc2Order[k] - 1 - a) / 8;
SetCharBit(p, j, getCharPos(key[(i + 1) % 2][b], a));
k++;
}
}
/*
cout << "before PC-2 of " << i << " stage" << endl;
Output(key[(i + 1) % 2]);
cout << endl << "subkey" << "[" << i << "]" << endl;
Output(subkey[i]);
cout << endl;
*/
}
}
void OutputSubkey()
{
int i = 0, j = 0, k = 0, m = 0;
for (m = 0; m <= 3; m++)
{
for (i = m * 4; i <= m * 4 + 3; i++)
{
cout << " subkey" << "[" << i << "]";
if (i < 10)
cout << " ";
else
cout << " ";
}
cout << endl << endl;
for (i = 0; i <= 5; i++)
{
for (j = m * 4; j <= m * 4 + 3; j++)
{
cout << " ";
for (k = 0; k <= 7; k++)
{
cout << ((subkey[j][i] >> (7 - k)) & 1);
}
cout << " ";
}
cout << endl;
}
cout << endl << endl;
}
cout << endl << endl;
}
//----------------------------------------------------------------------------------------
//encipher or decipher
DWORD WINAPI ENORDE(LPVOID lpParameter)
{
int e = *(int*)lpParameter;
int stage = 0;
char text[9], LP[4], RP[4], EOut[7], SIn[7], SOut[5], POut[5];
while (1)
{
if (WaitForSingleObject(hKEY, INFINITE) == WAIT_OBJECT_0) //等待KEY线程生成密钥结束
{
IT(text, LP, RP, e);
for (stage = 0; stage <= 15; stage++)
{
EBOX(EOut, RP);
SBOX(stage, SIn, EOut, SOut);
PBOX(SOut, POut);
CHANGE(LP, RP, POut);
}
FT(LP, RP, e);
break;
}
}
return 1;
}
//get plaintext or ciphertext
int getText(char choice)
{
int i;
char source = TextSource();
EN_OR_DE = 0;
if ('2' == source)
{
if ('1' == choice)
cout << "enter plaintext ";
else
{
cout << "enter ciphertext ";
EN_OR_DE = 1;
}
cin >> TotalText;
return strlen(TotalText);
}
else if ('1' == source)
{
ifstream fin;
if ('1' == choice)
fin.open("e:\\plaintext.txt", ios::binary);
else
{
fin.open("e:\\ciphertext.txt", ios::binary);
EN_OR_DE = 1;
}
if (!fin)
{
cout << "can't find the file...." << endl;
system("pause");
return 0;
}
else
{
char ch;
for (i = 0; i < 9999; i++)
{
fin.get(ch);
if (fin.eof())
{
TotalText[i] = '\0';
break;
}
else
{
TotalText[i] = ch;
}
}
}
fin.close();
}
return i;
}
//add q at the last of the text
int AddText(int n)
{
int len = n;
int a = len % 8;
int i = 0;
if (a != 0)
{
for (i = len; i < len + (8 - a); i++)
TotalText[i] = 'q';
TotalText[i] = '\0';
len = len + 8 - a;
}
return len;
}
void IT(char *text, char *LP, char *RP, int e)
{
int i = 0, j = 0;
int a = 0, b = 0;
char PreText[9];
PreText[8] = '\0';
for (i = 0; i <= 7; i++)
PreText[i] = TotalText[e * 8 + i];
//IT
for (i = 0; i <= 7; i++)
{
for (j = 0; j <= 7; j++)
{
a = ITOrder[i * 8 + j] % 8;
b = (ITOrder[i * 8 + j] - a) / 8;
if (0 == a)
a = 8;
else
b++;
//get a & b
text[i] = (text[i] | (~x[j]))&(((((PreText[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]));
}
}
text[8] = '\0';
//divide text into right part and left part
for (i = 0; i <= 7; i++)
{
if (i <= 3)
LP[i] = text[i];
else
RP[i - 4] = text[i];
}
//LP[4] = '\0';
//RP[4] = '\0';
}
void EBOX(char *EOut, char *RP)
{
int i = 0, j = 0, a = 0, b = 0;
for (i = 0; i <= 5; i++)
{
for (j = 0; j <= 7; j++)
{
a = EOrder[i * 8 + j] % 8;
b = (EOrder[i * 8 + j] - a) / 8;
if (0 == a)
a = 8;
else
b++;
//get a & b
EOut[i] = (EOut[i] | (~x[j]))&((((RP[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]);
}
}
}
void SBOX(int stage, char *SIn, char *EOut, char *SOut)
{
//decide encipher or decipher
if (1 == EN_OR_DE)
stage = 15 - stage;
int i = 0, j = 0;
//xor
for (i = 0; i <= 5; i++)
SIn[i] = EOut[i] ^ subkey[stage][i];
//SBox
int xpos = 0, ypos = 0, pos = 0;
int a = 0, b = 0;
for (i = 0; i <= 7; i++)
{
ypos = 0;
//找到每一块的初始位
a = (i * 6) % 8; //第a位(按数组,从0开始)
b = (i * 6 - a) / 8; //第b个字符(按数组,从0开始)
xpos = getCharPos(SIn[b], a) * 2;
for (j = 1; j <= 4; j++)
{
a++;
if (8 == a)
{
a = 0;
b++;
}
ypos += getCharPos(SIn[b], a)*pow(2, 4 - j);
}
a++;
if (8 == a)
{
a = 0;
b++;
}
xpos += getCharPos(SIn[b], a);
//by now,we get xpos and ypos
//we use 0x0F and 0xF0
if (i != 0 && 0 == i % 2)
pos++;
SOut[pos] = (SOut[pos] & z[i % 2]) | (y[SBox[i][xpos * 16 + ypos]] << (((i + 1) % 2) * 4));
}
}
void PBOX(char *SOut, char *POut)
{
int i = 0, j = 0;
int a = 0, b = 0;
for (i = 0; i <= 3; i++)
{
for (j = 0; j <= 7; j++)
{
a = POrder[i * 8 + j] % 8;
b = (POrder[i * 8 + j] - a) / 8;
if (0 == a)
a = 8;
else
b++;
//get a & b
POut[i] = (POut[i] | (~x[j]))&((((SOut[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]);
}
}
}
void CHANGE(char *LP, char *RP, char *POut)
{
char w[5];
int i = 0;
for (i = 0; i <= 3; i++)
w[i] = RP[i];
for (i = 0; i <= 3; i++)
RP[i] = POut[i] ^ LP[i];
for (i = 0; i <= 3; i++)
LP[i] = w[i];
}
void FT(char *LP, char *RP, int e)
{
char AfterText[9];
char SubAimText[9];
int i = 0, j = 0;
int a = 0, b = 0;
for (i = 0; i <= 3; i++)
AfterText[i] = RP[i];
for (i = 4; i <= 7; i++)
AfterText[i] = LP[i - 4];
//FT
for (i = 0; i <= 7; i++)
{
for (j = 0; j <= 7; j++)
{
a = FTOrder[i * 8 + j] % 8;
b = (FTOrder[i * 8 + j] - a) / 8;
if (0 == a)
a = 8;
else
b++;
//get a & b
SubAimText[i] = (SubAimText[i] | (~x[j]))&((((AfterText[b - 1] >> (8 - a)) & 1) << (7 - j)) | x[j]);
}
}
//write SubAimText to AimText
for (i = 0; i <= 7; i++)
AimText[e * 8 + i] = SubAimText[i];
}
void Write2File(int n)
{
ofstream fout;
if (0 == EN_OR_DE)
{
remove("e:\\ciphertext.txt");
fout.open("e:\\ciphertext.txt", ios::binary);
}
else
{
n = DeleteQ(n);
remove("e:\\plaintext.txt");
fout.open("e:\\plaintext.txt", ios::binary);
}
for (int i = 0; i < n; i++)
fout << AimText[i];
fout.close();
}
int DeleteQ(int len)
{
int i = len - 1;
while ('q' == AimText[i])
{
i--;
cout << i;
}
i++;
AimText[i] = '\0';
return i;
}
//----------------------------------------------------------------------------------------
//wait
DWORD WINAPI WAIT(LPVOID lpParameter)
{
int block = *(int*)lpParameter;
int finished = 0;
while (finished<=block)
{
if (WaitForSingleObject(hENORDE[finished], INFINITE) == WAIT_OBJECT_0) // 等待加密/解密过程结束
{
finished++;
}
}
return 0;
}
//----------------------------------------------------------------------------------------
CPC.h
cpp
#include "Common.h"
int CPCEn();
int CPCDe();
CPC.cpp
cpp
#include <iostream>
#include <fstream>
#include "CPC.h"
using namespace std;
//Column Permutation Cipher Encryption
//key必须是小写英文字母
//plaintext大小写字母均可
//null letter 是 q
int CPCEn()
{
char plaintext[99];
char ciphertext[99];
char key[99];
char choice = TextSource();
if (choice == '2')
{
cout << "enter plaintext ";
cin >> plaintext;
}
else if (choice == '1')
{
ifstream fin;
fin.open("e:\\plaintext.txt");
if (!fin)
{
cout << "can't find the file...." << endl;
system("pause");
return 0;
}
else
{
fin.getline(plaintext, 99);
}
fin.close();
}
cout << " enter key ";
cin >> key;
//对plaintext的长度进行调整
int d = strlen(key);
int temp = strlen(plaintext);
int i;
if (temp % d != 0) {
for (i = 1; i <= d - (temp % d); i++)
{
plaintext[temp + i - 1] = 'q';
}
plaintext[temp + i] = '\0';
}
//cout << plaintext << endl;
//从key中获得order
int j, k;
int order[99];
k = 1;
for (i = 'a'; i <= 'z'; i++)
{
for (j = 0; j < strlen(key); j++)
{
if (key[j] == i)
{
order[j] = k;
k++;
}
}
}
order[d] = '\0';
cout << "order ";
for (i = 0; i<d; i++)
cout << order[i];
cout << endl;
//加密过程
//不用计算机实现时,需要先把plaintext写进矩阵,再按照order提取出来,形成ciphertext
//在用计算机实现时可以直接把plaintext转变为ciphertext
k = 0;
for (j = 0; j < d; j++)
{
for (i = 0; i < strlen(plaintext) / d; i++)
{
ciphertext[k] = plaintext[i*d + order[j]-1];
k++;
}
}
ciphertext[k] = '\0';
cout << "ciphertext " << ciphertext;
ofstream fout;
fout.open("e:\\ciphertext.txt");
fout << ciphertext << endl;
fout.close();
system("pause");
return 1;
}
//Column Permutation Cipher Decryption
//null letter 是 q
int CPCDe()
{
char plaintext[99];
char ciphertext[99];
char key[99];
char choice = TextSource();
if (choice == '2')
{
cout << "enter ciphertext ";
cin >> ciphertext;
}
else if (choice == '1')
{
ifstream fin;
fin.open("e:\\ciphertext.txt");
if (!fin)
{
cout << "can't find the file...." << endl;
system("pause");
return 0;
}
else
{
fin.getline(ciphertext, 99);
}
fin.close();
}
cout << " enter key ";
cin >> key;
//从key中获得order
int i,j, k;
int d = strlen(key);
int order[99];
k = 1;
for (i = 'a'; i <= 'z'; i++)
{
for (j = 0; j < strlen(key); j++)
{
if (key[j] == i)
{
order[j] = k;
k++;
}
}
}
order[d] = '\0';
cout << "order ";
for (i = 0; i<d; i++)
cout << order[i];
cout << endl;
//process of decrypyion
k = -1;
for (i = 0; i < strlen(ciphertext); i++)
{
if (0 == i % (strlen(ciphertext) / d))
k++;
plaintext[d* (i % (strlen(ciphertext) / d)) + order[k] - 1] = ciphertext[i];
}
i--;
while('q' == plaintext[i])
{
i--;
}
plaintext[i+1] = '\0';
cout << "plaintext " << plaintext<<endl;
ofstream fout;
fout.open("e:\\plaintext.txt");
fout << plaintext << endl;
fout.close();
system("pause");
return 1;
}
Vigenere.h
cpp
#include "Common.h"
int VigenereEn();
int VigenereDe();
Vigenere.cpp
cpp
#include <iostream>
#include <fstream>
#include "Vigenere.h"
using namespace std;
//Vigenere Encryption
//keyword必须是小写英文字母
//plaintext大小写字母均可
int VigenereEn()
{
char plaintext[99];
char ciphertext[99];
char keyword[99];
int i=0;
int flag=0;
char choice = TextSource();
if (choice == '2')
{
cout << "enter plaintext ";
cin >> plaintext;
}
else if (choice == '1')
{
ifstream fin;
fin.open("e:\\plaintext.txt");
if (!fin)
{
cout << "can't find the file...." << endl;
system("pause");
return 0;
}
else
{
fin.getline(plaintext, 99);
}
fin.close();
}
cout<< " enter keyword ";
cin>>keyword;
for(i=0;i<strlen(plaintext);i++)
{
if(plaintext[i]>='a'&&plaintext[i]<='z')
flag=0;
else if(plaintext[i]>='A'&&plaintext[i]<='Z')
{
flag=1;
plaintext[i]=plaintext[i]+32;
}
ciphertext[i]=((plaintext[i]-96)+(keyword[i%strlen(keyword)]-96)-1)%26+96;
if (96 == ciphertext[i])
ciphertext[i] = 'z';
if(1==flag)
ciphertext[i]=ciphertext[i]-32;
}
ciphertext[i]='\0';
cout << " ciphertext "<< ciphertext<<endl;
ofstream fout;
fout.open("e:\\ciphertext.txt");
fout << ciphertext << endl;
fout.close();
system("pause");
return 1;
}
//Vigenere Decryption
//keyword必须是小写英文字母
//ciphertext大小写字母均可
int VigenereDe()
{
char plaintext[99];
char ciphertext[99];
char keyword[99];
char choice = TextSource();
if (choice == '2')
{
cout << "enter ciphertext ";
cin >> ciphertext;
}
else if (choice == '1')
{
ifstream fin;
fin.open("e:\\ciphertext.txt");
if (!fin)
{
cout << "can't find the file...." << endl;
system("pause");
return 0;
}
else
{
fin.getline(ciphertext, 99);
}
fin.close();
}
cout<< " enter keyword ";
cin>>keyword;
int i=0;
int flag=0;
for(i=0;i<strlen(ciphertext);i++)
{
if(ciphertext[i]>='a'&&ciphertext[i]<='z')
flag=0;
else if(ciphertext[i]>='A'&&ciphertext[i]<='Z')
{
flag=1;
ciphertext[i]=ciphertext[i]+32;
}
if(ciphertext[i]<keyword[i%strlen(keyword)])
plaintext[i]=26-(keyword[i%strlen(keyword)]-ciphertext[i])+'a';
else
plaintext[i] =ciphertext[i] - keyword[i%strlen(keyword)] + 'a';
if(1==flag)
plaintext[i]=plaintext[i]-32;
}
plaintext[i]='\0';
cout << " plaintext "<< plaintext<<endl;
ofstream fout;
fout.open("e:\\plaintext.txt");
fout << plaintext << endl;
fout.close();
system("pause");
return 1;
}
Common.h
cpp
#pragma once
char TextSource();
Common.cpp
cpp
#include <iostream>
#include <conio.h>
#include "Common.h"
using namespace std;
char TextSource()
{
char choice;
do
{
system("cls");
cout << "Please choose plaintext/ciphertext source:" << endl;;
cout << "1.File" << endl;
cout << "2.Keyboard" << endl << endl;
choice = getch();
} while (choice != '1' && choice != '2');
system("cls");
return choice;
}
Order.h
cpp
#pragma once
char x[8] = { 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE };
char y[17] = { 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF };
char z[2] = { 0x0F,0xF0 };
int ITOrder[] = { 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 };
int Pc1Order[56] = {
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 };
int Pc2Order[48] =
{
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
};
int EOrder[48] = {
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 };
int SBox[8][64] =
{
{ 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 }
};
int POrder[] = { 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 };
int FTOrder[64] = {
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 };