cdes加密演算法
DES雖然不難但是挺繁復的,代碼如下,關鍵點都有英文解釋,仔細看。各個函數的功能都可以從函數名看出來。
#include "pch.h"
#include "misc.h"
#include "des.h"
NAMESPACE_BEGIN(CryptoPP)
/* Tables defined in the Data Encryption Standard documents
* Three of these tables, the initial permutation, the final
* permutation and the expansion operator, are regular enough that
* for speed, we hard-code them. They're here for reference only.
* Also, the S and P boxes are used by a separate program, gensp.c,
* to build the combined SP box, Spbox[]. They're also here just
* for reference.
*/
#ifdef notdef
/* initial permutation IP */
static byte ip[] = {
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
};
/* final permutation IP^-1 */
static byte fp[] = {
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
};
/* expansion operation matrix */
static byte ei[] = {
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
};
/* The (in)famous S-boxes */
static byte sbox[8][64] = {
/* S1 */
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
};
/* 32-bit permutation function P used on the output of the S-boxes */
static byte p32i[] = {
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
};
#endif
/* permuted choice table (key) */
static const byte pc1[] = {
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
};
/* number left rotations of pc1 */
static const byte totrot[] = {
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
/* permuted choice key (table) */
static const byte pc2[] = {
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
};
/* End of DES-defined tables */
/* bit 0 is left-most in byte */
static const int bytebit[] = {
0200,0100,040,020,010,04,02,01
};
/* Set key (initialize key schele array) */
DES::DES(const byte *key, CipherDir dir)
: k(32)
{
SecByteBlock buffer(56+56+8);
byte *const pc1m=buffer; /* place to modify pc1 into */
byte *const pcr=pc1m+56; /* place to rotate pc1 into */
byte *const ks=pcr+56;
register int i,j,l;
int m;
for (j=0; j<56; j++) { /* convert pc1 to bits of key */
l=pc1[j]-1; /* integer bit location */
m = l & 07; /* find bit */
pc1m[j]=(key[l>>3] & /* find which key byte l is in */
bytebit[m]) /* and which bit of that byte */
? 1 : 0; /* and store 1-bit result */
}
for (i=0; i<16; i++) { /* key chunk for each iteration */
memset(ks,0,8); /* Clear key schele */
for (j=0; j<56; j++) /* rotate pc1 the right amount */
pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
/* rotate left and right halves independently */
for (j=0; j<48; j++){ /* select bits indivially */
/* check bit that goes to ks[j] */
if (pcr[pc2[j]-1]){
/* mask it in if it's there */
l= j % 6;
ks[j/6] |= bytebit[l] >> 2;
}
}
/* Now convert to odd/even interleaved form for use in F */
k[2*i] = ((word32)ks[0] << 24)
| ((word32)ks[2] << 16)
| ((word32)ks[4] << 8)
| ((word32)ks[6]);
k[2*i+1] = ((word32)ks[1] << 24)
| ((word32)ks[3] << 16)
| ((word32)ks[5] << 8)
| ((word32)ks[7]);
}
if (dir==DECRYPTION) // reverse key schele order
for (i=0; i<16; i+=2)
{
std::swap(k[i], k[32-2-i]);
std::swap(k[i+1], k[32-1-i]);
}
}
/* End of C code common to both versions */
/* C code only in portable version */
// Richard Outerbridge's initial permutation algorithm
/*
inline void IPERM(word32 &left, word32 &right)
{
word32 work;
work = ((left >> 4) ^ right) & 0x0f0f0f0f;
right ^= work;
left ^= work << 4;
work = ((left >> 16) ^ right) & 0xffff;
right ^= work;
left ^= work << 16;
work = ((right >> 2) ^ left) & 0x33333333;
left ^= work;
right ^= (work << 2);
work = ((right >> 8) ^ left) & 0xff00ff;
left ^= work;
right ^= (work << 8);
right = rotl(right, 1);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = rotl(left, 1);
}
inline void FPERM(word32 &left, word32 &right)
{
word32 work;
right = rotr(right, 1);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = rotr(left, 1);
work = ((left >> 8) ^ right) & 0xff00ff;
right ^= work;
left ^= work << 8;
work = ((left >> 2) ^ right) & 0x33333333;
right ^= work;
left ^= work << 2;
work = ((right >> 16) ^ left) & 0xffff;
left ^= work;
right ^= work << 16;
work = ((right >> 4) ^ left) & 0x0f0f0f0f;
left ^= work;
right ^= work << 4;
}
*/
// Wei Dai's modification to Richard Outerbridge's initial permutation
// algorithm, this one is faster if you have access to rotate instructions
// (like in MSVC)
inline void IPERM(word32 &left, word32 &right)
{
word32 work;
right = rotl(right, 4U);
work = (left ^ right) & 0xf0f0f0f0;
left ^= work;
right = rotr(right^work, 20U);
work = (left ^ right) & 0xffff0000;
left ^= work;
right = rotr(right^work, 18U);
work = (left ^ right) & 0x33333333;
left ^= work;
right = rotr(right^work, 6U);
work = (left ^ right) & 0x00ff00ff;
left ^= work;
right = rotl(right^work, 9U);
work = (left ^ right) & 0xaaaaaaaa;
left = rotl(left^work, 1U);
right ^= work;
}
inline void FPERM(word32 &left, word32 &right)
{
word32 work;
right = rotr(right, 1U);
work = (left ^ right) & 0xaaaaaaaa;
right ^= work;
left = rotr(left^work, 9U);
work = (left ^ right) & 0x00ff00ff;
right ^= work;
left = rotl(left^work, 6U);
work = (left ^ right) & 0x33333333;
right ^= work;
left = rotl(left^work, 18U);
work = (left ^ right) & 0xffff0000;
right ^= work;
left = rotl(left^work, 20U);
work = (left ^ right) & 0xf0f0f0f0;
right ^= work;
left = rotr(left^work, 4U);
}
// Encrypt or decrypt a block of data in ECB mode
void DES::ProcessBlock(const byte *inBlock, byte * outBlock) const
{
word32 l,r,work;
#ifdef IS_LITTLE_ENDIAN
l = byteReverse(*(word32 *)inBlock);
r = byteReverse(*(word32 *)(inBlock+4));
#else
l = *(word32 *)inBlock;
r = *(word32 *)(inBlock+4);
#endif
IPERM(l,r);
const word32 *kptr=k;
for (unsigned i=0; i<8; i++)
{
work = rotr(r, 4U) ^ kptr[4*i+0];
l ^= Spbox[6][(work) & 0x3f]
^ Spbox[4][(work >> 8) & 0x3f]
^ Spbox[2][(work >> 16) & 0x3f]
^ Spbox[0][(work >> 24) & 0x3f];
work = r ^ kptr[4*i+1];
l ^= Spbox[7][(work) & 0x3f]
^ Spbox[5][(work >> 8) & 0x3f]
^ Spbox[3][(work >> 16) & 0x3f]
^ Spbox[1][(work >> 24) & 0x3f];
work = rotr(l, 4U) ^ kptr[4*i+2];
r ^= Spbox[6][(work) & 0x3f]
^ Spbox[4][(work >> 8) & 0x3f]
^ Spbox[2][(work >> 16) & 0x3f]
^ Spbox[0][(work >> 24) & 0x3f];
work = l ^ kptr[4*i+3];
r ^= Spbox[7][(work) & 0x3f]
^ Spbox[5][(work >> 8) & 0x3f]
^ Spbox[3][(work >> 16) & 0x3f]
^ Spbox[1][(work >> 24) & 0x3f];
}
FPERM(l,r);
#ifdef IS_LITTLE_ENDIAN
*(word32 *)outBlock = byteReverse(r);
*(word32 *)(outBlock+4) = byteReverse(l);
#else
*(word32 *)outBlock = r;
*(word32 *)(outBlock+4) = l;
#endif
}
void DES_EDE_Encryption::ProcessBlock(byte *inoutBlock) const
{
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
}
void DES_EDE_Encryption::ProcessBlock(const byte *inBlock, byte *outBlock) const
{
e.ProcessBlock(inBlock, outBlock);
d.ProcessBlock(outBlock);
e.ProcessBlock(outBlock);
}
void DES_EDE_Decryption::ProcessBlock(byte *inoutBlock) const
{
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
}
void DES_EDE_Decryption::ProcessBlock(const byte *inBlock, byte *outBlock) const
{
d.ProcessBlock(inBlock, outBlock);
e.ProcessBlock(outBlock);
d.ProcessBlock(outBlock);
}
void TripleDES_Encryption::ProcessBlock(byte *inoutBlock) const
{
e1.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e2.ProcessBlock(inoutBlock);
}
void TripleDES_Encryption::ProcessBlock(const byte *inBlock, byte *outBlock) const
{
e1.ProcessBlock(inBlock, outBlock);
d.ProcessBlock(outBlock);
e2.ProcessBlock(outBlock);
}
void TripleDES_Decryption::ProcessBlock(byte *inoutBlock) const
{
d1.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d2.ProcessBlock(inoutBlock);
}
void TripleDES_Decryption::ProcessBlock(const byte *inBlock, byte *outBlock) const
{
d1.ProcessBlock(inBlock, outBlock);
e.ProcessBlock(outBlock);
d2.ProcessBlock(outBlock);
}
2. 求一個用c語言寫的DES加密演算法~~
using system;
using system.security.cryptography;
using system.io;
using system.text;
public class encryptstringdes {
public static void main(string);
return;
}
// 使用utf8函數加密輸入參數
utf8encoding utf8encoding = new utf8encoding();
byte.tochararray());
// 方式一:調用默認的des實現方法des_csp.
des des = des.create();
// 方式二:直接使用des_csp()實現des的實體
//des_csp des = new des_csp();
// 初始化des加密的密鑰和一個隨機的、8比特的初始化向量(iv)
byte iv = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
des.key = key;
des.iv = iv;
// 建立加密流
symmetricstreamencryptor sse = des.createencryptor();
// 使用cryptomemorystream方法獲取加密過程的輸出
cryptomemorystream cms = new cryptomemorystream();
// 將symmetricstreamencryptor流中的加密數據輸出到cryptomemorystream中
sse.setsink(cms);
// 加密完畢,將結果輸出到控制台
sse.write(inputbytearray);
sse.closestream();
// 獲取加密數據
byte);
}
console.writeline();
//上面演示了如何進行加密,下面演示如何進行解密
symmetricstreamdecryptor ssd = des.createdecryptor();
cms = new cryptomemorystream();
ssd.setsink(cms);
ssd.write(encrypteddata);
ssd.closestream();
byte decryptedchararray = utf8encoding.getchars(decrypteddata);
console.writeline("解密後數據:");
console.write(decryptedchararray);
console.writeline();
}
}
編譯:
d:\csharp>csc des_demo.cs
microsoft (r) c# compiler version 7.00.8905
right (c) microsoft corp 2000. all rights reserved.
運行實例:
d:\csharp>des_demo.exe 使用c#編寫des加密程序的framework
加密結果:
3d 22 64 c6 57 d1 c4 c3 cf 77 ce 2f d0 e1 78 2a 4d ed 7a a8 83 f9 0e 14 e1 ba 38
7b 06 41 8d b5 e9 3f 00 0d c3 28 d1 f9 6d 17 4b 6e a7 41 68 40
3. des加密演算法(c/c++)
des.h文件:
#ifndefCRYPTOPP_DES_H
#defineCRYPTOPP_DES_H
#include"cryptlib.h"
#include"misc.h"
NAMESPACE_BEGIN(CryptoPP)
classDES:publicBlockTransformation
{
public:
DES(constbyte*userKey,CipherDir);
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const
{DES::ProcessBlock(inoutBlock,inoutBlock);}
enum{KEYLENGTH=8,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
protected:
staticconstword32Spbox[8][64];
SecBlock<word32>k;
};
classDESEncryption:publicDES
{
public:
DESEncryption(constbyte*userKey)
:DES(userKey,ENCRYPTION){}
};
classDESDecryption:publicDES
{
public:
DESDecryption(constbyte*userKey)
:DES(userKey,DECRYPTION){}
};
classDES_EDE_Encryption:publicBlockTransformation
{
public:
DES_EDE_Encryption(constbyte*userKey)
:e(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe,d;
};
classDES_EDE_Decryption:publicBlockTransformation
{
public:
DES_EDE_Decryption(constbyte*userKey)
:d(userKey,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd,e;
};
classTripleDES_Encryption:publicBlockTransformation
{
public:
TripleDES_Encryption(constbyte*userKey)
:e1(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION),
e2(userKey+2*DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe1,d,e2;
};
classTripleDES_Decryption:publicBlockTransformation
{
public:
TripleDES_Decryption(constbyte*userKey)
:d1(userKey+2*DES::KEYLENGTH,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION),
d2(userKey,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd1,e,d2;
};
NAMESPACE_END
#endif
des.cpp文件:
//des.cpp-modifiedbyWeiDaifrom:
/*
*
*circa1987,'s1977
*publicdomaincode.,but
*theactualencrypt/
*Outerbridge'sDEScodeasprintedinSchneier's"AppliedCryptography."
*
*Thiscodeisinthepublicdomain.Iwouldappreciatebugreportsand
*enhancements.
*
*PhilKarnKA9Q,[email protected],August1994.
*/
#include"pch.h"
#include"misc.h"
#include"des.h"
NAMESPACE_BEGIN(CryptoPP)
/*
*Threeofthesetables,theinitialpermutation,thefinal
*,areregularenoughthat
*forspeed,wehard-codethem.They'rehereforreferenceonly.
*Also,,gensp.c,
*tobuildthecombinedSPbox,Spbox[].They'realsoherejust
*forreference.
*/
#ifdefnotdef
/*initialpermutationIP*/
staticbyteip[]={
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
};
/*finalpermutationIP^-1*/
staticbytefp[]={
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
};
/*expansionoperationmatrix*/
staticbyteei[]={
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
};
/*The(in)famousS-boxes*/
staticbytesbox[8][64]={
/*S1*/
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
};
/*32--boxes*/
staticbytep32i[]={
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
};
#endif
/*permutedchoicetable(key)*/
staticconstbytepc1[]={
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
};
/*numberleftrotationsofpc1*/
staticconstbytetotrot[]={
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
/*permutedchoicekey(table)*/
staticconstbytepc2[]={
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
};
/*EndofDES-definedtables*/
/*bit0isleft-mostinbyte*/
staticconstintbytebit[]={
0200,0100,040,020,010,04,02,01
};
/*Setkey(initializekeyschelearray)*/
DES::DES(constbyte*key,CipherDirdir)
:k(32)
{
SecByteBlockbuffer(56+56+8);
byte*constpc1m=buffer;/*placetomodifypc1into*/
byte*constpcr=pc1m+56;/*placetorotatepc1into*/
byte*constks=pcr+56;
registerinti,j,l;
intm;
for(j=0;j<56;j++){/*convertpc1tobitsofkey*/
l=pc1[j]-1;/*integerbitlocation*/
m=l&07;/*findbit*/
pc1m[j]=(key[l>>3]&/*findwhichkeybytelisin*/
bytebit[m])/*andwhichbitofthatbyte*/
?1:0;/*andstore1-bitresult*/
}
for(i=0;i<16;i++){/*keychunkforeachiteration*/
memset(ks,0,8);/*Clearkeyschele*/
for(j=0;j<56;j++)/*rotatepc1therightamount*/
pcr[j]=pc1m[(l=j+totrot[i])<(j<28?28:56)?l:l-28];
/**/
for(j=0;j<48;j++){/*selectbitsindivially*/
/*checkbitthatgoestoks[j]*/
if(pcr[pc2[j]-1]){
/*maskitinifit'sthere*/
l=j%6;
ks[j/6]|=bytebit[l]>>2;
}
}
/*Nowconverttoodd/eveninterleavedformforuseinF*/
k[2*i]=((word32)ks[0]<<24)
|((word32)ks[2]<<16)
|((word32)ks[4]<<8)
|((word32)ks[6]);
k[2*i+1]=((word32)ks[1]<<24)
|((word32)ks[3]<<16)
|((word32)ks[5]<<8)
|((word32)ks[7]);
}
if(dir==DECRYPTION)//reversekeyscheleorder
for(i=0;i<16;i+=2)
{
std::swap(k[i],k[32-2-i]);
std::swap(k[i+1],k[32-1-i]);
}
}
/**/
/*Ccodeonlyinportableversion*/
//RichardOuterbridge'sinitialpermutationalgorithm
/*
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
work=((left>>4)^right)&0x0f0f0f0f;
right^=work;
left^=work<<4;
work=((left>>16)^right)&0xffff;
right^=work;
left^=work<<16;
work=((right>>2)^left)&0x33333333;
left^=work;
right^=(work<<2);
work=((right>>8)^left)&0xff00ff;
left^=work;
right^=(work<<8);
right=rotl(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotl(left,1);
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotr(left,1);
work=((left>>8)^right)&0xff00ff;
right^=work;
left^=work<<8;
work=((left>>2)^right)&0x33333333;
right^=work;
left^=work<<2;
work=((right>>16)^left)&0xffff;
left^=work;
right^=work<<16;
work=((right>>4)^left)&0x0f0f0f0f;
left^=work;
right^=work<<4;
}
*/
//WeiDai''sinitialpermutation
//algorithm,
//(likeinMSVC)
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
right=rotl(right,4U);
work=(left^right)&0xf0f0f0f0;
left^=work;
right=rotr(right^work,20U);
work=(left^right)&0xffff0000;
left^=work;
right=rotr(right^work,18U);
work=(left^right)&0x33333333;
left^=work;
right=rotr(right^work,6U);
work=(left^right)&0x00ff00ff;
left^=work;
right=rotl(right^work,9U);
work=(left^right)&0xaaaaaaaa;
left=rotl(left^work,1U);
right^=work;
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1U);
work=(left^right)&0xaaaaaaaa;
right^=work;
left=rotr(left^work,9U);
work=(left^right)&0x00ff00ff;
right^=work;
left=rotl(left^work,6U);
work=(left^right)&0x33333333;
right^=work;
left=rotl(left^work,18U);
work=(left^right)&0xffff0000;
right^=work;
left=rotl(left^work,20U);
work=(left^right)&0xf0f0f0f0;
right^=work;
left=rotr(left^work,4U);
}
//
voidDES::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
word32l,r,work;
#ifdefIS_LITTLE_ENDIAN
l=byteReverse(*(word32*)inBlock);
r=byteReverse(*(word32*)(inBlock+4));
#else
l=*(word32*)inBlock;
r=*(word32*)(inBlock+4);
#endif
IPERM(l,r);
constword32*kptr=k;
for(unsignedi=0;i<8;i++)
{
work=rotr(r,4U)^kptr[4*i+0];
l^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=r^kptr[4*i+1];
l^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
work=rotr(l,4U)^kptr[4*i+2];
r^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=l^kptr[4*i+3];
r^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
}
FPERM(l,r);
#ifdefIS_LITTLE_ENDIAN
*(word32*)outBlock=byteReverse(r);
*(word32*)(outBlock+4)=byteReverse(l);
#else
*(word32*)outBlock=r;
*(word32*)(outBlock+4)=l;
#endif
}
voidDES_EDE_Encryption::ProcessBlock(byte*inoutBlock)const
{
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
}
voidDES_EDE_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e.ProcessBlock(outBlock);
}
voidDES_EDE_Decryption::ProcessBlock(byte*inoutBlock)const
{
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
}
voidDES_EDE_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d.ProcessBlock(outBlock);
}
voidTripleDES_Encryption::ProcessBlock(byte*inoutBlock)const
{
e1.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e2.ProcessBlock(inoutBlock);
}
voidTripleDES_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e1.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e2.ProcessBlock(outBlock);
}
voidTripleDES_Decryption::ProcessBlock(byte*inoutBlock)const
{
d1.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d2.ProcessBlock(inoutBlock);
}
voidTripleDES_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d1.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d2.ProcessBlock(outBlock);
}
NAMESPACE_END
程序運行如下:
4. 用c語言寫des加密演算法
#include <stdio.h> #include <string.h> #include <windows.h> #include <conio.h> #include "Schedle.h" class CShift{ public: DWORDLONG mask[16]; int step[16]; CShift(){ for(int i=0;i<16;i++){ step[i]=2; mask[i]=0xc000000; } step[0]=step[1]=step[8]=step[15]=1; mask[0]=mask[1]=mask[8]=mask[15]=0x8000000; } }; class CDES{ public: CDES(){ m_dwlKey=0; m_dwlData=0; ConvertTableToMask(dwlKey_PC_1,64); //PrintTable(dwlKey_PC_1,7,8); ConvertTableToMask(dwlKey_PC_2,56); ConvertTableToMask(dwlData_IP,64); ConvertTableToMask(dwlData_Expansion,32); ConvertTableToMask(dwlData_FP,64); ConvertTableToMask(dwlData_P,32); Generate_S(); } void PrintBit(DWORDLONG); void EncryptKey(char *); unsigned char* EncryptData(unsigned char *); unsigned char* DescryptData(unsigned char*); private: void ConvertTableToMask(DWORDLONG *,int); void Generate_S(void); void PrintTable(DWORDLONG*,int,int); DWORDLONG ProcessByte(unsigned char*,BOOL); DWORDLONG PermuteTable(DWORDLONG,DWORDLONG*,int); void Generate_K(void); void EncryptKernel(void); DWORDLONG Generate_B(DWORDLONG,DWORDLONG*); /*For verify schele permutation only*/ DWORDLONG UnPermuteTable(DWORDLONG,DWORDLONG*,int); /**************************************/ DWORDLONG dwlData_S[9][4][16]; CShift m_shift; DWORDLONG m_dwlKey; DWORDLONG m_dwlData; DWORDLONG m_dwl_K[17]; }; void CDES::EncryptKey(char *key){ printf("\nOriginal Key: %s",key); m_dwlKey=ProcessByte((unsigned char*)key,TRUE); // PrintBit(m_dwlKey); m_dwlKey=PermuteTable(m_dwlKey,dwlKey_PC_1,56); // PrintBit(m_dwlKey); Generate_K(); // printf("\n******************************************\n"); } void CDES::Generate_K(void){ DWORDLONG C[17],D[17],tmp; C[0]=m_dwlKey>>28; D[0]=m_dwlKey&0xfffffff; for(int i=1;i<=16;i++){ tmp=(C[i-1]&m_shift.mask[i-1])>>(28-m_shift.step[i-1]); C[i]=((C[i-1]<<m_shift.step[i-1])|tmp)&0x0fffffff; tmp=(D[i-1]&m_shift.mask[i-1])>>(28-m_shift.step[i-1]); D[i]=((D[i-1]<<m_shift.step[i-1])|tmp)&0x0fffffff; m_dwl_K[i]=(C[i]<<28)|D[i]; m_dwl_K[i]=PermuteTable(m_dwl_K[i],dwlKey_PC_2,48); } } DWORDLONG CDES::ProcessByte(unsigned char *key,BOOL shift){ unsigned char tmp; DWORDLONG byte=0; int i=0; while(i<8){ while(*key){ if(byte!=0) byte<<=8; tmp=*key; if(shift) tmp<<=1; byte|=tmp; i++; key++; } if(i<8) byte<<=8; i++; } return byte; } DWORDLONG CDES::PermuteTable(DWORDLONG dwlPara,DWOR 基於des演算法的rfid安全系統
DLONG* dwlTable,int nDestLen){ int i=0; DWORDLONG tmp=0,moveBit; while(i<nDestLen){ moveBit=1; if(dwlTable[i]&dwlPara){ moveBit<<=nDestLen-i-1; tmp|=moveBit; } i++; } return tmp; } DWORDLONG CDES::UnPermuteTable(DWORDLONG dwlPara,DWORDLONG* dwlTable,int nDestLen){ DWORDLONG tmp=0; int i=nDestLen-1; while(dwlPara!=0){ if(dwlPara&0x01) tmp|=dwlTable[i]; dwlPara>>=1; i--; } return tmp; } void CDES::PrintTable(DWORDLONG *dwlPara,int col,int row){ int i,j; for(i=0;i<row;i++){ printf("\n"); getch(); for(j=0;j<col;j++) PrintBit(dwlPara[i*col+j]); } } void CDES::PrintBit(DWORDLONG bitstream){ char out[76]; int i=0,j=0,space=0; while(bitstream!=0){ if(bitstream&0x01) out[i++]='1'; else out[i++]='0'; j++; if(j%8==0){ out[i++]=' '; space++; } bitstream=bitstream>>1; } out[i]='\0'; strcpy(out,strrev(out)); printf("%s **:%d\n",out,i-space); } void CDES::ConvertTableToMask(DWORDLONG *mask,int max){ int i=0; DWORDLONG nBit=1; while(mask[i]!=0){ nBit=1; nBit<<=max-mask[i]; mask[i++]=nBit; } } void CDES::Generate_S(void){ int i; int j,m,n; m=n=0; j=1; for(i=0;i<512;i++){ dwlData_S[j][m][n]=OS[i]; n=(n+1)%16; if(!n){ m=(m+1)%4; if(!m) j++; } } } unsigned char * CDES::EncryptData(unsigned char *block){ unsigned char *EncrytedData=new unsigned char(15); printf("\nOriginal Data: %s\n",block); m_dwlData=ProcessByte(block,0); // PrintBit(m_dwlData); m_dwlData=PermuteTable(m_dwlData,dwlData_IP,64); EncryptKernel(); // PrintBit(m_dwlData); DWORDLONG bit6=m_dwlData; for(int i=0;i<11;i++){ EncrytedData[7-i]=(unsigned char)(bit6&0x3f)+46; bit6>>=6; } EncrytedData[11]='\0'; printf("\nAfter Encrypted: %s",EncrytedData); for(i=0;i<8;i++){ EncrytedData[7-i]=(unsigned char)(m_dwlData&0xff); m_dwlData>>=8; } EncrytedData[8]='\0'; return EncrytedData; } void CDES::EncryptKernel(void){ int i=1; DWORDLONG L[17],R[17],B[9],EK,PSB; L[0]=m_dwlData>>32; R[0]=m_dwlData&0xffffffff; for(i=1;i<=16;i++){ L[i]=R[i-1]; R[i-1]=PermuteTable(R[i-1],dwlData_Expansion,48); //Expansion R EK=R[i-1]^m_dwl_K[i]; //E Permutation PSB=Generate_B(EK,B); //P Permutation R[i]=L[i-1]^PSB; } R[16]<<=32; m_dwlData=R[16]|L[16]; m_dwlData=PermuteTable(m_dwlData,dwlData_FP,64); } unsigned char* CDES::DescryptData(unsigned char *desData){ int i=1; unsigned char *DescryptedData=new unsigned char(15); DWORDLONG L[17],R[17],B[9],EK,PSB; DWORDLONG dataPara; dataPara=ProcessByte(desData,0); dataPara=PermuteTable(dataPara,dwlData_IP,64); R[16]=dataPara>>32; L[16]=dataPara&0xffffffff; for(i=16;i>=1;i--){ R[i-1]=L[i]; L[i]=PermuteTable(L[i],dwlData_Expansion,48); //Expansion L EK=L[i]^m_dwl_K[i]; //E Permutation PSB=Generate_B(EK,B); //P Permutation L[i-1]=R[i]^PSB; } L[0]<<=32; dataPara=L[0]|R[0]; dataPara=PermuteTable(dataPara,dwlData_FP,64); // PrintBit(dataPara); for(i=0;i<8;i++){ DescryptedData[7-i]=(unsigned char)(dataPara&0xff); dataPara>>=8; } DescryptedData[8]='\0'; printf("\nAfter Decrypted: %s\n",DescryptedData); return DescryptedData; } DWORDLONG CDES::Generate_B(DWORDLONG EKPara,DWORDLONG *block){ int i,m,n; DWORDLONG tmp=0; for(i=8;i>0;i--){ block[i]=EKPara&0x3f; m=(int)(block[i]&0x20)>>4; m|=block[i]&0x01; n=(int)(block[i]<<1)>>2; block[i]=dwlData_S[i][m][n]; EKPara>>=6; } for(i=1;i<=8;i++){ tmp|=block[i]; tmp<<=4; } tmp>>=4; tmp=PermuteTable(tmp,dwlData_P,32); return tmp; } void main(void){ CDES des; des.EncryptKey("12345678"); unsigned char *result=des.EncryptData((unsigned char*)"DemoData"); des.DescryptData(result); }[1]
5. des加密演算法c語言
http://..com/question/80040477.html?si=4
http://..com/question/40022679.html?si=5
6. 如何實現C語言的DES加密演算法實現,請關注
可能很長 ,這是在我以前一個程序里摘出來的。 原理:用戶輸入創建密碼,機器讀取,並把每一位密碼進行加密,這里就是把每一位的 ASCII碼加一(也可以有其他的加密方式),然後保存在文件里。解密時從文件中讀取保存的亂碼,然後把它每一位的asc
7. 基於C語言的DES加密演算法的實現 要怎麼寫啊
首先c語言要熟悉,然後去圖書館借一本加密解密的書,要裡面有c語言des實現代碼的(這種書是有的,我看到過)。論文先對加密解密的歷史及發展現狀進行介紹,然後著重對des加密的發展歷史及原理進行闡述(以上內容要多借幾本相關書綜合一下用自己的語言表達出來)。然後對des的演算法寫個程序(可以利用書裡面的程序),然後運行結果截幾張圖下來。最後總結一下,論文就可以了。
8. 求C或C++的DES加密演算法
/* d3des.h -
*
* Headers and defines for d3des.c
* Graven Imagery, 1992.
*
* Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
* (GEnie : OUTER; CIS : [71755,204])
*/
#define D2_DES /* include double-length support */
#define D3_DES /* include triple-length support */
#ifdef D3_DES
#ifndef D2_DES
#define D2_DES /* D2_DES is needed for D3_DES */
#endif
#endif
#define EN0 0 /* MODE == encrypt */
#define DE1 1 /* MODE == decrypt */
/* A useful alias on 68000-ish machines, but NOT USED HERE. */
typedef union {
unsigned long blok[2];
unsigned short word[4];
unsigned char byte[8];
} M68K;
extern void deskey(unsigned char *, short);
/* hexkey[8] MODE
* Sets the internal key register according to the hexadecimal
* key contained in the 8 bytes of hexkey, according to the DES,
* for encryption or decryption according to MODE.
*/
extern void usekey(unsigned long *);
/* cookedkey[32]
* Loads the internal key register with the data in cookedkey.
*/
extern void cpkey(unsigned long *);
/* cookedkey[32]
* Copies the contents of the internal key register into the storage
* located at &cookedkey[0].
*/
extern void des(unsigned char *, unsigned char *);
/* from[8] to[8]
* Encrypts/Decrypts (according to the key currently loaded in the
* internal key register) one block of eight bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/
#ifdef D2_DES
#define desDkey(a,b) des2key((a),(b))
extern void des2key(unsigned char *, short);
/* hexkey[16] MODE
* Sets the internal key registerS according to the hexadecimal
* keyS contained in the 16 bytes of hexkey, according to the DES,
* for DOUBLE encryption or decryption according to MODE.
* NOTE: this clobbers all three key registers!
*/
extern void Ddes(unsigned char *, unsigned char *);
/* from[8] to[8]
* Encrypts/Decrypts (according to the keyS currently loaded in the
* internal key registerS) one block of eight bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/
extern void D2des(unsigned char *, unsigned char *);
/* from[16] to[16]
* Encrypts/Decrypts (according to the keyS currently loaded in the
* internal key registerS) one block of SIXTEEN bytes at address 'from'
* into the block at address 'to'. They can be the same.
*/
extern void makekey(char *, unsigned char *);
/* *password, single-length key[8]
* With a double-length default key, this routine hashes a NULL-terminated
* string into an eight-byte random-looking key, suitable for use with the
* deskey() routine.
*/
#define makeDkey(a,b) make2key((a),(b))
extern void make2key(char *, unsigned char *);
/* *password, double-length key[16]
* With a double-length default key, this routine hashes a NULL-terminated
* string into a sixteen-byte random-looking key, suitable for use with the
* des2key() routine.
*/
#ifndef D3_DES /* D2_DES only */
#define useDkey(a) use2key((a))
#define cpDkey(a) cp2key((a))
extern void use2key(unsigned long *);
/* cookedkey[64]
* Loads the internal key registerS with the data in cookedkey.
* NOTE: this clobbers all three key registers!
*/
extern void cp2key(unsigned long *);
/* cookedkey[64]
* Copies the contents of the internal key registerS into the storage
* located at &cookedkey[0].
*/
#else /* D3_DES too */
#define useDkey(a) use3key((a))
#define cpDkey(a) cp3key((a))
extern void des3key(unsigned char *, short);
/* hexkey[24] MODE
* Sets the internal key registerS according to the hexadecimal
* keyS contained in the 24 bytes of hexkey, according to the DES,
* for DOUBLE encryption or decryption according to MODE.
*/
extern void use3key(unsigned long *);
/* cookedkey[96]
* Loads the 3 internal key registerS with the data in cookedkey.
*/
extern void cp3key(unsigned long *);
/* cookedkey[96]
* Copies the contents of the 3 internal key registerS into the storage
* located at &cookedkey[0].
*/
extern void make3key(char *, unsigned char *);
/* *password, triple-length key[24]
* With a triple-length default key, this routine hashes a NULL-terminated
* string into a twenty-four-byte random-looking key, suitable for use with
* the des3key() routine.
*/
#endif /* D3_DES */
#endif /* D2_DES */
9. 用C語言實現DES加密演算法!
l iceEncryptText 文本加密解密
http://dl.icese.net/src.php?f=iceEncryptText.src.rar
10. DES加密演算法C語言實現
#include<iostream.h>
class SubKey{ //定義子密鑰為一個類
public:
int key[8][6];
}subkey[16]; //定義子密鑰對象數組
class DES{
int encipher_decipher; //判斷加密還是解密
int key_in[8][8]; //用戶原始輸入的64位二進制數
int key_out[8][7]; //除去每行的最後一位校驗位
int c0_d0[8][7]; //存儲經PC-1轉換後的56位數據
int c0[4][7],d0[4][7]; //分別存儲c0,d0
int text[8][8]; //64位明文
int text_ip[8][8]; //經IP轉換過後的明文
int A[4][8],B[4][8]; //A,B分別存儲經IP轉換過後明文的兩部分,便於交換
int temp[8][6]; //存儲經擴展置換後的48位二進制值
int temp1[8][6]; //存儲和子密鑰異或後的結果
int s_result[8][4]; //存儲經S變換後的32位值
int text_p[8][4]; //經P置換後的32位結果
int secret_ip[8][8]; //經逆IP轉換後的密文
public:
void Key_Putting();
void PC_1();
int function(int,int); //異或
void SubKey_Proction();
void IP_Convert();
void f();
void _IP_Convert();
void Out_secret();
};
void DES::Key_Putting() //得到密鑰中對演算法有用的56位
{
cout<<"請輸入64位的密鑰(8行8列且每行都得有奇數個1):\n";
for(int i=0;i<8;i++)
for(int j=0;j<8;j++){
cin>>key_in[i][j];
if(j!=7) key_out[i][j]=key_in[i][j];
}
}
void DES::PC_1() //PC-1置換函數
{
int pc_1[8][7]={ //PC-1
{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 i,j;
for(i=0;i<8;i++)
for(j=0;j<7;j++)
c0_d0[i][j]=key_out[ (pc_1[i][j]-1)/8 ][ (pc_1[i][j]-1)%8 ];
}
int DES::function(int a,int b) //模擬二進制數的異或運算,a和b為整型的0和1,返回值為整型的0或1
{
if(a!=b)return 1;
else return 0;
}
void DES::SubKey_Proction() //生成子密鑰
{
int move[16][2]={ //循環左移的位數
1 , 1 , 2 , 1 ,
3 , 2 , 4 , 2 ,
5 , 2 , 6 , 2 ,
7 , 2 , 8 , 2 ,
9 , 1, 10 , 2,
11 , 2, 12 , 2,
13 , 2, 14 , 2,
15 , 2, 16 , 1
};
int pc_2[8][6]={ //PC-2
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
};
for(int i=0;i<16;i++) //生成子密鑰
{
int j,k;
int a[2],b[2];
int bb[28],cc[28];
for(j=0;j<4;j++)
for(k=0;k<7;k++)
c0[j][k]=c0_d0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
d0[j-4][k]=c0_d0[j][k];
for(j=0;j<4;j++)
for(k=0;k<7;k++){
bb[7*j+k]=c0[j][k];
cc[7*j+k]=d0[j][k];
}
for(j=0;j<move[i][1];j++){
a[j]=bb[j];
b[j]=cc[j];
}
for(j=0;j<28-move[i][1];j++){
bb[j]=bb[j+1];
cc[j]=cc[j+1];
}
for(j=0;j<move[i][1];j++){
bb[27-j]=a[j];
cc[27-j]=b[j];
}
for(j=0;j<28;j++){
c0[j/7][j%7]=bb[j];
d0[j/7][j%7]=cc[j];
}
for(j=0;j<4;j++) //L123--L128是把c0,d0合並成c0_d0
for(k=0;k<7;k++)
c0_d0[j][k]=c0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
c0_d0[j][k]=d0[j-4][k];
for(j=0;j<8;j++) //對Ci,Di進行PC-2置換
for(k=0;k<6;k++)
subkey[i].key[j][k]=c0_d0[ (pc_2[j][k]-1)/7 ][ (pc_2[j][k]-1)%7 ];
}
}
void DES::IP_Convert()
{
int IP[8][8]={ //初始置換IP矩陣
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
};
cout<<"你好,你要加密還是解密?加密請按1號鍵(輸入1),解密請按2號鍵,並確定."<<'\n';
cin>>encipher_decipher;
char * s;
if(encipher_decipher==1) s="明文";
else s="密文";
cout<<"請輸入64位"<<s<<"(二進制):\n";
int i,j;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
cin>>text[i][j];
for(i=0;i<8;i++) //進行IP變換
for(j=0;j<8;j++)
text_ip[i][j]=text[ (IP[i][j]-1)/8 ][ (IP[i][j]-1)%8 ];
}