
{
调用时只需要调用下面两个函数即可。
function EncryStr(Str, Key: String): String
function DecryStr(Str, Key: String): String
function EncryStrHex(Str, Key: String): String
function DecryStrHex(StrHex, Key: String): String
}
interface
uses
SysUtils, Variants,strutils
type
TKeyByte = array[0..5] of Byte
TDesMode = (dmEncry, dmDecry)
function EncryStr(Str, Key: String): String
function DecryStr(Str, Key: String): String
function EncryStrHex(Str, Key: String): String
function DecryStrHex(StrHex, Key: String): String
const
BitIP: array[0..63] of Byte = //初始值置IP
(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 )
BitCP: array[0..63] of Byte = //逆初始置IP-1
( 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 )
BitExp: array[0..47] of Integer = // 位选择函数E
( 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 )
BitPM: array[0..31] of Byte = //置换函数P
( 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 )
sBox: array[0..7] of array[0..63] of Byte =//S盒
( ( 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 ) )
BitPMC1: array[0..55] of Byte = //选择置换PC-1
( 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 )
BitPMC2: array[0..47] of Byte =//选择置换PC-2
( 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 )
var
subKey: array[0..15] of TKeyByte
implementation
procedure initPermutation(var inData: array of Byte)
var
newData: array[0..7] of Byte
i: Integer
begin
FillChar(newData, 8, 0)
for i := 0 to 63 do
if (inData[BitIP[i] shr 3] and (1 shl (7- (BitIP[i] and $07)))) <>0 then
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)))
for i := 0 to 7 do inData[i] := newData[i]
end
procedure conversePermutation(var inData: array of Byte)
var
newData: array[0..7] of Byte
i: Integer
begin
FillChar(newData, 8, 0)
for i := 0 to 63 do
if (inData[BitCP[i] shr 3] and (1 shl (7-(BitCP[i] and $07)))) <>0 then
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)))
for i := 0 to 7 do inData[i] := newData[i]
end
procedure expand(inData: array of Bytevar outData: array of Byte)
var
i: Integer
begin
FillChar(outData, 6, 0)
for i := 0 to 47 do
if (inData[BitExp[i] shr 3] and (1 shl (7-(BitExp[i] and $07)))) <>0 then
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)))
end
procedure permutation(var inData: array of Byte)
var
newData: array[0..3] of Byte
i: Integer
begin
FillChar(newData, 4, 0)
for i := 0 to 31 do
if (inData[BitPM[i] shr 3] and (1 shl (7-(BitPM[i] and $07)))) <>0 then
newData[i shr 3] := newData[i shr 3] or (1 shl (7-(i and $07)))
for i := 0 to 3 do inData[i] := newData[i]
end
function si(s,inByte: Byte): Byte
var
c: Byte
begin
c := (inByte and $20) or ((inByte and $1e) shr 1) or
((inByte and $01) shl 4)
Result := (sBox[s][c] and $0f)
end
procedure permutationChoose1(inData: array of Byte
var outData: array of Byte)
var
i: Integer
begin
FillChar(outData, 7, 0)
for i := 0 to 55 do
if (inData[BitPMC1[i] shr 3] and (1 shl (7-(BitPMC1[i] and $07)))) <>0 then
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)))
end
procedure permutationChoose2(inData: array of Byte
var outData: array of Byte)
var
i: Integer
begin
FillChar(outData, 6, 0)
for i := 0 to 47 do
if (inData[BitPMC2[i] shr 3] and (1 shl (7-(BitPMC2[i] and $07)))) <>0 then
outData[i shr 3] := outData[i shr 3] or (1 shl (7-(i and $07)))
end
procedure cycleMove(var inData: array of BytebitMove: Byte)
var
i: Integer
begin
for i := 0 to bitMove - 1 do
begin
inData[0] := (inData[0] shl 1) or (inData[1] shr 7)
inData[1] := (inData[1] shl 1) or (inData[2] shr 7)
inData[2] := (inData[2] shl 1) or (inData[3] shr 7)
inData[3] := (inData[3] shl 1) or ((inData[0] and $10) shr 4)
inData[0] := (inData[0] and $0f)
end
end
procedure makeKey(inKey: array of Bytevar outKey: array of TKeyByte)
const
bitDisplace: array[0..15] of Byte =
( 1,1,2,2, 2,2,2,2, 1,2,2,2, 2,2,2,1 )
var
outData56: array[0..6] of Byte
key28l: array[0..3] of Byte
key28r: array[0..3] of Byte
key56o: array[0..6] of Byte
i: Integer
begin
permutationChoose1(inKey, outData56)
key28l[0] := outData56[0] shr 4
key28l[1] := (outData56[0] shl 4) or (outData56[1] shr 4)
key28l[2] := (outData56[1] shl 4) or (outData56[2] shr 4)
key28l[3] := (outData56[2] shl 4) or (outData56[3] shr 4)
key28r[0] := outData56[3] and $0f
key28r[1] := outData56[4]
key28r[2] := outData56[5]
key28r[3] := outData56[6]
for i := 0 to 15 do
begin
cycleMove(key28l, bitDisplace[i])
cycleMove(key28r, bitDisplace[i])
key56o[0] := (key28l[0] shl 4) or (key28l[1] shr 4)
key56o[1] := (key28l[1] shl 4) or (key28l[2] shr 4)
key56o[2] := (key28l[2] shl 4) or (key28l[3] shr 4)
key56o[3] := (key28l[3] shl 4) or (key28r[0])
key56o[4] := key28r[1]
key56o[5] := key28r[2]
key56o[6] := key28r[3]
permutationChoose2(key56o, outKey[i])
end
end
procedure encry(inData, subKey: array of Byte
var outData: array of Byte)
var
outBuf: array[0..5] of Byte
buf: array[0..7] of Byte
i: Integer
begin
expand(inData, outBuf)
for i := 0 to 5 do outBuf[i] := outBuf[i] xor subKey[i]
buf[0] := outBuf[0] shr 2
buf[1] := ((outBuf[0] and $03) shl 4) or (outBuf[1] shr 4)
buf[2] := ((outBuf[1] and $0f) shl 2) or (outBuf[2] shr 6)
buf[3] := outBuf[2] and $3f
buf[4] := outBuf[3] shr 2
buf[5] := ((outBuf[3] and $03) shl 4) or (outBuf[4] shr 4)
buf[6] := ((outBuf[4] and $0f) shl 2) or (outBuf[5] shr 6)
buf[7] := outBuf[5] and $3f
for i := 0 to 7 do buf[i] := si(i, buf[i])
for i := 0 to 3 do outBuf[i] := (buf[i*2] shl 4) or buf[i*2+1]
permutation(outBuf)
for i := 0 to 3 do outData[i] := outBuf[i]
end
procedure desData(desMode: TDesMode
inData: array of Bytevar outData: array of Byte)
// inData, outData 都为8Bytes,否则出错
var
i, j: Integer
temp, buf: array[0..3] of Byte
begin
for i := 0 to 7 do outData[i] := inData[i]
initPermutation(outData)
if desMode = dmEncry then
begin
for i := 0 to 15 do
begin
for j := 0 to 3 do temp[j] := outData[j]//temp = Ln
for j := 0 to 3 do outData[j] := outData[j + 4]//Ln+1 = Rn
encry(outData, subKey[i], buf) //Rn ==Kn==>buf
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j] //Rn+1 = Ln^buf
end
for j := 0 to 3 do temp[j] := outData[j + 4]
for j := 0 to 3 do outData[j + 4] := outData[j]
for j := 0 to 3 do outData[j] := temp[j]
end
else if desMode = dmDecry then
begin
for i := 15 downto 0 do
begin
for j := 0 to 3 do temp[j] := outData[j]
for j := 0 to 3 do outData[j] := outData[j + 4]
encry(outData, subKey[i], buf)
for j := 0 to 3 do outData[j + 4] := temp[j] xor buf[j]
end
for j := 0 to 3 do temp[j] := outData[j + 4]
for j := 0 to 3 do outData[j + 4] := outData[j]
for j := 0 to 3 do outData[j] := temp[j]
end
conversePermutation(outData)
end
//////////////////////////////////////////////////////////////
function EncryStr(Str, Key: String): String
var
StrByte, OutByte, KeyByte: array[0..7] of Byte
StrResult: String
I, J: Integer
begin
if (Length(Str) >0) and (Ord(Str[Length(Str)]) = 0) then
raise Exception.Create('Error: the last char is NULL char.')
if Length(Key) <8 then
while Length(Key) <8 do Key := Key + Chr(0)
while Length(Str) mod 8 <>0 do Str := Str + Chr(0)
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1])
makeKey(keyByte, subKey)
StrResult := ''
for I := 0 to Length(Str) div 8 - 1 do
begin
for J := 0 to 7 do
StrByte[J] := Ord(Str[I * 8 + J + 1])
desData(dmEncry, StrByte, OutByte)
for J := 0 to 7 do
StrResult := StrResult + Chr(OutByte[J])
end
Result := StrResult
end
function DecryStr(Str, Key: String): String
var
StrByte, OutByte, KeyByte: array[0..7] of Byte
StrResult: String
I, J: Integer
begin
if Length(Key) <8 then
while Length(Key) <8 do Key := Key + Chr(0)
for J := 0 to 7 do KeyByte[J] := Ord(Key[J + 1])
makeKey(keyByte, subKey)
StrResult := ''
for I := 0 to Length(Str) div 8 - 1 do
begin
for J := 0 to 7 do StrByte[J] := Ord(Str[I * 8 + J + 1])
desData(dmDecry, StrByte, OutByte)
for J := 0 to 7 do
StrResult := StrResult + Chr(OutByte[J])
end
while (Length(StrResult) >0) and
(Ord(StrResult[Length(StrResult)]) = 0) do
Delete(StrResult, Length(StrResult), 1)
Result := StrResult
end
///////////////////////////////////////////////////////////
function EncryStrHex(Str, Key: String): String
var
StrResult, TempResult, Temp: String
I,k: Integer
begin
TempResult := EncryStr(Str, Key)
StrResult := ''
for I := 0 to Length(TempResult) - 1 do
begin
Temp := Format('%x', [Ord(TempResult[I + 1])])
if Length(Temp) = 1 then Temp := '0' + Temp
StrResult := StrResult + Temp
end
k:=0
for i := 0 to length(StrResult) - 1 do
k:=k + ord((StrResult[i+1]))
Result := StrResult + intToHex(Byte(k),2)
end
function DecryStrHex(StrHex, Key: String): String
function HexToInt(Hex: String): Integer
var
I, Res: Integer
ch: Char
begin
Res := 0
for I := 0 to Length(Hex) - 1 do
begin
ch := Hex[I + 1]
if (ch >= '0') and (ch <= '9') then
Res := Res * 16 + Ord(ch) - Ord('0')
else if (ch >= 'A') and (ch <= 'F') then
Res := Res * 16 + Ord(ch) - Ord('A') + 10
else if (ch >= 'a') and (ch <= 'f') then
Res := Res * 16 + Ord(ch) - Ord('a') + 10
else raise Exception.Create('Error: not a Hex String')
end
Result := Res
end
var
Str, Temp: String
I,k: Integer
begin
Str := ''
if length(StrHex)<=2 then
begin
result:=''
exit
end
K:=0
for i := 0 to length(StrHex) - 3 do
k:=k + ord((StrHex[i+1]))
try
if Byte(k)<>Byte(strToInt('$' + rightStr(StrHex,2))) then
begin
result:=''
exit
end
delete(StrHex,length(StrHex)-1,2)
for I := 0 to Length(StrHex) div 2 - 1 do
begin
Temp := Copy(StrHex, I * 2 + 1, 2)
Str := Str + Chr(HexToInt(Temp))
end
Result := DecryStr(Str, Key)
except
result:=''
end
end
end.
#include <iostream>#include <fstream>
#include <bitset>
#include <string>
using namespace std
bitset<64> key
bitset<48> subKey[16]
int 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}
int IP_1[] = {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}
int 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 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}
int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}
int E[] = {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 S_BOX[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}
},
{
{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 P[] = {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 }
bitset<32> f(bitset<32> R, bitset<48> k)
{
bitset<48> expandR
// 第一步:扩展置换,32 -> 48
for(int i=0 i<48 ++i)
expandR[47-i] = R[32-E[i]]
// 第二步:异或
expandR = expandR ^ k
// 第三步:查找S_BOX置换表
bitset<32> output
int x = 0
for(int i=0 i<48 i=i+6)
{
int row = expandR[47-i]*2 + expandR[47-i-5]
int col = expandR[47-i-1]*8 + expandR[47-i-2]*4 + expandR[47-i-3]*2 + expandR[47-i-4]
int num = S_BOX[i/6][row][col]
bitset<4> binary(num)
output[31-x] = binary[3]
output[31-x-1] = binary[2]
output[31-x-2] = binary[1]
output[31-x-3] = binary[0]
x += 4
}
// 第四步:P-置换,32 -> 32
bitset<32> tmp = output
for(int i=0 i<32 ++i)
output[31-i] = tmp[32-P[i]]
return output
}
bitset<28> leftShift(bitset<28> k, int shift)
{
bitset<28> tmp = k
for(int i=27 i>=0 --i)
{
if(i-shift<0)
k[i] = tmp[i-shift+28]
else
k[i] = tmp[i-shift]
}
return k
}
void generateKeys()
{
bitset<56> realKey
bitset<28> left
bitset<28> right
bitset<48> compressKey
// 去掉奇偶标记位,将64位密钥变成56位
for (int i=0 i<56 ++i)
realKey[55-i] = key[64 - PC_1[i]]
// 生成子密钥,保存在 subKeys[16] 中
for(int round=0 round<16 ++round)
{
// 前28位与后28位
for(int i=28 i<56 ++i)
left[i-28] = realKey[i]
for(int i=0 i<28 ++i)
right[i] = realKey[i]
// 左移
left = leftShift(left, shiftBits[round])
right = leftShift(right, shiftBits[round])
// 压缩置换,由56位得到48位子密钥
for(int i=28 i<56 ++i)
realKey[i] = left[i-28]
for(int i=0 i<28 ++i)
realKey[i] = right[i]
for(int i=0 i<48 ++i)
compressKey[47-i] = realKey[56 - PC_2[i]]
subKey[round] = compressKey
}
}
bitset<64> charToBitset(const char s[8])
{
bitset<64> bits
for(int i=0 i<8 ++i)
for(int j=0 j<8 ++j)
bits[i*8+j] = ((s[i]>>j) & 1)
return bits
}
bitset<64> encrypt(bitset<64>& plain)
{
bitset<64> cipher
bitset<64> currentBits
bitset<32> left
bitset<32> right
bitset<32> newLeft
// 第一步:初始置换IP
for(int i=0 i<64 ++i)
currentBits[63-i] = plain[64-IP[i]]
// 第二步:获取 Li 和 Ri
for(int i=32 i<64 ++i)
left[i-32] = currentBits[i]
for(int i=0 i<32 ++i)
right[i] = currentBits[i]
// 第三步:共16轮迭代
for(int round=0 round<16 ++round)
{
newLeft = right
right = left ^ f(right,subKey[round])
left = newLeft
}
// 第四步:合并L16和R16,注意合并为 R16L16
for(int i=0 i<32 ++i)
cipher[i] = left[i]
for(int i=32 i<64 ++i)
cipher[i] = right[i-32]
// 第五步:结尾置换IP-1
currentBits = cipher
for(int i=0 i<64 ++i)
cipher[63-i] = currentBits[64-IP_1[i]]
// 返回密文
return cipher
}
bitset<64> decrypt(bitset<64>& cipher)
{
bitset<64> plain
bitset<64> currentBits
bitset<32> left
bitset<32> right
bitset<32> newLeft
// 第一步:初始置换IP
for(int i=0 i<64 ++i)
currentBits[63-i] = cipher[64-IP[i]]
// 第二步:获取 Li 和 Ri
for(int i=32 i<64 ++i)
left[i-32] = currentBits[i]
for(int i=0 i<32 ++i)
right[i] = currentBits[i]
// 第三步:共16轮迭代(子密钥逆序应用)
for(int round=0 round<16 ++round)
{
newLeft = right
right = left ^ f(right,subKey[15-round])
left = newLeft
}
// 第四步:合并L16和R16,注意合并为 R16L16
for(int i=0 i<32 ++i)
plain[i] = left[i]
for(int i=32 i<64 ++i)
plain[i] = right[i-32]
// 第五步:结尾置换IP-1
currentBits = plain
for(int i=0 i<64 ++i)
plain[63-i] = currentBits[64-IP_1[i]]
// 返回明文
return plain
}
int main() {
string s = "romantic"
string k = "12345678"
bitset<64> plain = charToBitset(s.c_str())
key = charToBitset(k.c_str())
// 生成16个子密钥
generateKeys()
bitset<64> cipher = encrypt(plain)
fstream file1
file1.open("D://a.txt", ios::binary | ios::out)
file1.write((char*)&cipher,sizeof(cipher))
file1.close()
bitset<64> temp
file1.open("D://a.txt", ios::binary | ios::in)
file1.read((char*)&temp, sizeof(temp))
file1.close()
bitset<64> temp_plain = decrypt(temp)
file1.open("D://b.txt", ios::binary | ios::out)
file1.write((char*)&temp_plain,sizeof(temp_plain))
file1.close()
return 0
}
首先新建头文件des_encode.H内容如下:
void EncodeMain() //EncodeMain function
void DecodeMain()//Sorry ,it has not used
void Decode(int *str,int *keychar) //decode :input 8 chars,8 keychars
void Encode(int *str,int *keychar) //encode: input 8 chars,8 keychars
void keyBuild(int *keychar)//create key array
void StrtoBin(int *midkey,int *keychar) //change into binary
void keyCreate(int *midkey2,int movebit,int i)//call by keyBuild
void EncodeData(int *lData,int *rData,int *srt) //encodedata function
void F(int *rData,int *key) //F function
void Expand(int *rData,int *rDataP) //Expand function
void ExchangeS(int *rDataP,int *rData) //S-diagram change
void ExchangeP(int *rData) //P change
void FillBin(int *rData,int n,int s)// data to binarycall by S-Diagram change function
void DecodeData(int *str,int *lData,int *rData) //DecodeData from binary
int IP1[]={58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,//initial change
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 IP2[]={40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,//opp initial change
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
}
int s[][4][16]={{ //S-diagram array
{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 Ex[48]={ 32,1,2,3,4,5, //Expand array
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 P[32]={16,7,20,21,//P-change
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 PC1[56]={57,49,41,33,25,17,9,//PC-1 in keyBuild
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,33,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4
}
int PC2[48]={14,17,11,24,1,5, //PC-2 in keyBuild
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
}
再创建des.cpp
内容如下:
#include<stdio.h>
#include<string.h>
#include"des_encode.h"
int key[16][48]
char str[8]
void main() //main function
{
EncodeMain()
}
void EncodeMain() //EncodeMain function
{
int i
char keychar[8]
int key2[8]
int strkey[8]
printf("请输入8个要加密的字符:\n")
for(i=0i<8i++)
scanf("%c",&str[i])
getchar()
for(i=0i<8i++)
strkey[i]=str[i]
printf("\n输入明文的十六进制为:\n")
for(i=0i<8i++)
printf("%10x",strkey[i])
printf("\n请输入密钥(8个字符):\n")
for(i=0i<8i++)
scanf("%c",&keychar[i])
for(i=0i<8i++)
key2[i]=keychar[i]
getchar()
// printf("%c",keychar[i])
Encode(strkey,key2)
printf("\n加密后十六进制密文是:\n")
for(i=0i<8i++)
printf("%10x",strkey[i])
printf("\n\n清输入解密密码\n")
for(i=0i<8i++)
scanf("%c",&keychar[i])
for(i=0i<8i++)
key2[i]=keychar[i]
Decode(strkey,key2)
for(i=0i<8i++)
printf("%10x",strkey[i])
for(i=0i<8i++)
str[i]=strkey[i]
printf("\n明文为:\t")
for(i=0i<8i++)
printf("%c",str[i])
printf("\n\n")
}
void keyBuild(int *keychar){//create key array
int i,j
int movebit[]={1,1,2,2,2,2,2,2,
1,2,2,2,2,2,2,1}
int midkey2[56]
int midkey[64]
StrtoBin(midkey,keychar)
for(i=0i<56i++)
midkey2[i]=midkey[PC1[i]-1]
for(i=0i<16i++)
keyCreate(midkey2,movebit[i],i)
}
void StrtoBin(int *midkey,int *keychar){ //change into binary
int trans[8],i,j,k,n
n=0
for(i=0i<8i++){
j=0
while(keychar[i]!=0){
trans[j]=keychar[i]%2
keychar[i]=keychar[i]/2
j++
}
for(k=jk<8k++)trans[k]=0
for(k=0k<8k++)
midkey[n++]=trans[7-k]
}
}
void keyCreate(int *midkey2,int movebit,int n){
int i,temp[4]
temp[0]=midkey2[0]
temp[1]=midkey2[1]
temp[2]=midkey2[28]
temp[3]=midkey2[29]
if(movebit==2){
for(i=0i<26i++){
midkey2[i]=midkey2[i+2]
midkey2[i+28]=midkey2[i+30]
}
midkey2[26]=temp[0]midkey2[27]=temp[1]
midkey2[54]=temp[2]midkey2[55]=temp[3] }
else
{ for(i=0i<27i++){
midkey2[i]=midkey2[i+1]
midkey2[i+28]=midkey2[i+29]
}
midkey2[27]=temp[0]midkey2[55]=temp[2]
}
for(i=0i<48i++)
key[n][i]=midkey2[PC2[i]-1]
}
void EncodeData(int *lData,int *rData,int *str){ //encodedata function
int i,j,temp[8],lint,rint//int h
int data[64]
lint=0,rint=0
for(i=0i<4i++){
j=0
while(str[i]!=0){
temp[j]=str[i]%2
str[i]=str[i]/2
j++
}
while(j<8)temp[j++]=0
for(j=0j<8j++)
lData[lint++]=temp[7-j]
j=0
while(str[i+4]!=0){
temp[j]=str[i+4]%2
str[i+4]=str[i+4]/2
j++
}
while(j<8)temp[j++]=0
for(j=0j<8j++)rData[rint++]=temp[7-j]
}
for(i=0i<32i++){
data[i]=lData[i]
data[i+32]=rData[i]
}
for(i=0i<32i++){
lData[i]=data[IP1[i]-1]//printf("P1:%5d:%5d,%5d\n",IP1[i],lData[i],data[IP1[i]-1])
rData[i]=data[IP1[i+32]-1]
}
}
void F(int *rData,int *key){ //F function
int i,rDataP[48]
Expand(rData,rDataP)
for(i=0i<48i++){
rDataP[i]=rDataP[i]^key[i]// printf("%10d",rDataP[i])if((i+1)%6==0)printf("\n")
}
ExchangeS(rDataP,rData)
ExchangeP(rData)
}
void Expand(int *rData,int *rDataP){ //Expand function
int i
for(i=0i<48i++)
rDataP[i]=rData[Ex[i]-1]
}
void ExchangeS(int *rDataP,int *rData){ //S-diagram change
int i,n,linex,liney
linex=liney=0
for(i=0i<48i+=6){
n=i/6//printf("%10d\n",(rDataP[i]<<1))
linex=(rDataP[i]<<1)+rDataP[i+5]
liney=(rDataP[i+1]<<3)+(rDataP[i+2]<<2)+(rDataP[i+3]<<1)+rDataP[i+4]
FillBin(rData,n,s[n][linex][liney])
}
}
void ExchangeP(int *rData){ //P change
int i,temp[32]
for(i=0i<32i++)
temp[i]=rData[i]
for(i=0i<32i++)
rData[i]=temp[P[i]-1]
}
void FillBin(int *rData,int n,int s){ // data to binarycall by S-Diagram change function
int temp[4],i
for(i=0i<4i++){
temp[i]=s%2
s=s/2
}
for(i=0i<4i++)
rData[n*4+i]=temp[3-i]
}
void DecodeData(int *str,int *lData,int *rData){//DecodeData from binary
int iint a,bint data[64]
a=0,b=0
for(i=0i<32i++){
data[i]=lData[i]
data[i+32]=rData[i]
}
for(i=0i<32i++){
lData[i]=data[IP2[i]-1]
rData[i]=data[IP2[i+32]-1]
}
for(i=0i<32i++){
a=(lData[i]&0x1)+(a<<1)
b=(rData[i]&0x1)+(b<<1)
if((i+1)%8==0){
str[i/8]=aa=0//printf("%d",i/8)
str[i/8+4]=bb=0//printf("%d",i/8+4)
}
}
}
void Encode(int *str,int *keychar){ //encode: input 8 chars,8 keychars
int lData[32],rData[32],temp[32],rDataP[48]
int i,j
keyBuild(keychar)
EncodeData(lData,rData,str)
for(i=0i<16i++){
for(j=0j<32j++)
temp[j]=rData[j]
F(rData,key[i])
for(j=0j<32j++){
rData[j]=rData[j]^lData[j]
}
for(j=0j<32j++)
lData[j]=temp[j]
}
DecodeData(str,rData,lData)
}
void Decode(int *str,int *keychar){ //decode :input 8 chars,8 keychars
int lData[32],rData[32],temp[32],rDataP[48]
int i,j
keyBuild(keychar)
EncodeData(lData,rData,str)//这个位置
for(i=0i<16i++){
for(j=0j<32j++)
temp[j]=rData[j]
F(rData,key[15-i])
for(j=0j<32j++){
rData[j]=rData[j]^lData[j]
}
for(j=0j<32j++){
lData[j]=temp[j]
}
}
DecodeData(str,rData,lData)
}
OK了
如果还有问题
给我发站内信
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)