?? des.pas
字號:
unit DES;
interface
Uses Windows, Classes, SysUtils, Math, Dialogs;
Type
TBitString = Array of Boolean;
PBitString = ^TBitString;
TSplitKeyParts = record
C:TBitString;
D:TBitString;
end;
TSplitKey = Array[0..16]Of TSplitKeyParts;
TConcatKey = Array[0..15]Of TBitString;
TIPKeyParts = record
L:TBitString;
R:TBitString;
end;
TIPKey = Array[0..16]OF TIPKeyParts;
Const
DES_PC1:Array[0..55] Of Byte = (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);
DES_PC2:Array[0..47] Of Byte = (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);
DES_IP:Array[0..63] Of Byte = (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);
DES_E:Array[0..47] Of Byte = (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);
S_BOXES:Array[0..7,0..3,0..15]Of Byte = (
((14,04,13,01,02,15,11,08,03,10,06,12,05,09,00,07),
(00,15,07,04,14,02,13,01,10,06,12,11,09,05,03,08),
(04,01,14,08,13,06,02,11,15,12,09,07,03,10,05,00),
(15,12,08,02,04,09,01,07,05,11,03,14,10,00,06,13)),
((15,01,08,14,06,11,03,04,09,07,02,13,12,00,05,10),
(03,13,04,07,15,02,08,14,12,00,01,10,06,09,11,05),
(00,14,07,11,10,04,13,01,05,08,12,06,09,03,02,15),
(13,08,10,01,03,15,04,02,11,06,07,12,00,05,14,09)),
((10,00,09,14,06,03,15,05,01,13,12,07,11,04,02,08),
(13,07,00,09,03,04,06,10,02,08,05,14,12,11,15,01),
(13,06,04,09,08,15,03,00,11,01,02,12,05,10,14,07),
(01,10,13,00,06,09,08,07,04,15,14,03,11,05,02,12)),
((07,13,14,03,00,06,09,10,01,02,08,05,11,12,04,15),
(13,08,11,05,06,15,00,03,04,07,02,12,01,10,14,09),
(10,06,09,00,12,11,07,13,15,01,03,14,05,02,08,04),
(13,15,00,06,10,01,13,08,09,04,05,11,12,07,02,14)),
((02,12,04,01,07,10,11,06,08,05,03,15,13,00,14,09),
(14,11,02,12,04,07,13,01,05,00,15,10,03,08,09,06),
(04,02,01,11,10,13,07,08,15,09,12,05,06,03,00,14),
(11,08,12,07,01,14,02,13,06,15,00,09,10,04,05,03)),
((12,01,10,15,09,02,06,08,00,13,03,04,14,07,05,11),
(10,15,04,02,07,12,09,05,06,01,13,14,00,11,03,08),
(09,14,15,05,02,08,12,03,07,00,04,10,01,13,11,06),
(04,03,02,12,09,05,15,10,11,14,01,04,06,00,08,13)),
((04,11,02,14,15,00,08,13,03,12,09,07,05,10,06,01),
(13,00,11,07,04,09,01,10,14,03,05,12,02,15,08,06),
(01,04,11,13,12,03,07,14,10,15,06,08,00,05,09,02),
(06,11,13,08,01,04,10,07,09,05,00,15,14,02,03,12)),
((13,02,08,04,06,15,11,01,10,09,03,14,05,00,12,07),
(01,15,13,08,10,03,07,04,12,05,06,11,00,14,09,02),
(07,11,04,01,09,12,14,02,00,06,10,13,15,03,05,08),
(02,01,14,07,04,10,08,13,15,12,09,00,03,05,06,11))
);
DES_P:Array[0..31] Of Byte = (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);
DES_REVERSE_IP:Array[0..63] Of Byte = (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);
DES_LSH:Array[0..15] Of Byte = (1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1);
Function BinToInt(S:TBitString):Integer;
Function IntToBin(N:Integer;Precision:Integer=8):TBitString;
Function BinToStr(Bits:TBitString):String;
Function StrToBin(S:String):TBitString;
Function AnsiStrToBin(S:String; Zeroes:Boolean=True):TBitString;
Function BinToAnsiStr(Bits:TBitString):String;
Procedure CopyBits(Var Dest:TBitString; Source:TBitString; NBits:Integer);
Function ConcatBits(Bits:Array Of TBitString):TBitString;
Function DESEncode(S,Key:String):TBitString;
Function DESDecode(S,Key:String):TBitString;
Function GetPermutedKey(Key:TBitString):TBitString;
Function GetPermutedKey2(Key:TBitString):TBitString;
Function GetSplitKey(Key:TBitString):TSplitKey;
Function GetConcatKey(Key:TSplitKey):TConcatKey;
Function GetIPKey(M:TBitString; ConcatKey:TConcatKey):TIPKey;
Function GetF(R,K:TBitString):TBitString;
Function GetSBox(Index:Integer; T:TBitString):TBitString;
Function GetReverseIP(RL:TBitString):TBitString;
Procedure ReverseSubKeys(Var Keys:TConcatKey);
implementation
Function ConcatBits(Bits:Array Of TBitString):TBitString;
Var
I,C:Integer;
Begin
SetLength(Result,0);
For C:=0 To Length(Bits)-1 Do
Begin
SetLength(Result,Length(Result)+Length(Bits[C]));
For I:=0 To Length(Bits[C])-1 Do
Result[Length(Result)-Length(Bits[C])+I]:=Bits[C][I];
End;
End;
Procedure CopyBits(Var Dest:TBitString; Source:TBitString; NBits:Integer);
Var
I:Integer;
Begin
SetLength(Dest,NBits);
For I:=0 To NBits-1 Do
Dest[I]:=Source[I];
End;
Function BinToInt(S: TBitString): Integer;
Var
L,I:Integer;
Begin
Result:=0;
L:=Length(S);
IF L=0 Then
Raise EConvertError.Create('Specified bit string is zero length');
For I:=L-1 DownTo 0 Do
Result:=Result+Ord(S[I])*Trunc(Power(2,L-I-1));
End;
Function IntToBin(N:Integer; Precision:Integer):TBitString;
Var
BitList:TList;
Bit:PBoolean;
Begin
SetLength(Result,0);
BitList:=TList.Create;
While N>0 Do
Begin
New(Bit);
Bit^:=Boolean(N mod 2);
BitList.Insert(0,Bit);
N:=N div 2;
End;
While BitList.Count<Precision Do
Begin
New(Bit);
Bit^:=False;
BitList.Insert(0,Bit);
End;
For N:=0 To BitList.Count-1 Do
Begin
SetLength(Result,N+1);
Bit:=BitList.Items[N];
Result[N]:=Bit^;
Dispose(Bit);
End;
BitList.Free;
end;
Function AnsiStrToBin(S: String; Zeroes:Boolean):TBitString;
Var
Temp,B:TBitString;
L,I,J:Integer;
Begin
L:=0;
SetLength(Result,L);
SetLength(Temp,L);
SetLength(B,0);
For I:=1 To Length(S) Do
Begin
B:=IntToBin(Ord(S[I]));
L:=L+Length(B);
SetLength(Temp,L);
For J:=0 To Length(B)-1 Do
Temp[Length(Temp)-Length(B)+J]:=B[J];
End;
Result:=Temp;
End;
Function BinToStr(Bits:TBitString):String;
Var
I,L:Integer;
Begin
Result:='';
L:=Length(Bits);
IF L=0 Then
Raise EConvertError.Create('Specified bit string is zero length');
For I:=0 To L-1 Do
IF Bits[I] Then Result:=Result+'1'
Else Result:=Result+'0';
End;
Function StrToBin(S:String):TBitString;
Var
I:Integer;
Begin
SetLength(Result,0);
For I:=1 To Length(S) Do
Begin
IF (S[I]<>'1')And(S[I]<>'0') Then
Raise EConvertError.Create(S+' is invalid binary string');
SetLength(Result,I);
Result[I-1]:=Boolean(StrToInt(S[I]));
End;
End;
Function BinToAnsiStr(Bits:TBitString):String;
Var
I:Integer;
B:TBitString;
Begin
Result:='';
SetLength(B,8);
I:=0;
While I<=Length(Bits)-8 Do
Begin
CopyMemory(B,Ptr(Integer(Bits)+I),8);
Result:=Result+Char(BinToInt(B));
Inc(I,8);
End;
End;
Function GetPermutedKey(Key:TBitString):TBitString;
Var
I:Integer;
Begin
SetLength(Result,Length(DES_PC1));
For I:=0 To Length(DES_PC1)-1 Do
Result[I]:=Key[DES_PC1[I]-1];
End;
Function GetPermutedKey2(Key:TBitString):TBitString;
Var
I:Integer;
Begin
SetLength(Result,Length(DES_PC2));
For I:=0 To Length(DES_PC2)-1 Do
Result[I]:=Key[DES_PC2[I]-1];
End;
Function GetSplitKey(Key:TBitString):TSplitKey;
Function LeftShift(Key:TBitString; N:Integer):TBitString;
Var
I,J:Integer;
Temp:TBitString;
Begin
SetLength(Result,28);
SetLength(Temp,28);
For I:=0 To 27 Do
Temp[I]:=Key[I];
For J:=1 To N Do
Begin
For I:=1 To 27 Do
Result[I-1]:=Temp[I];
Result[27]:=Temp[0];
For I:=0 To 27 Do
Temp[I]:=Result[I];
End;
End;
Var
I,J:Integer;
Begin
For J:=1 To 16 Do
Begin
SetLength(Result[J].C,28);
SetLength(Result[J].D,28);
End;
CopyBits(Result[0].C,Key,28);
CopyBits(Result[0].D,TBitString(Integer(Key)+28),28);
For I:=1 To 16 Do
Begin
Result[I].C:=LeftShift(Result[I-1].C,DES_LSH[I-1]);
Result[I].D:=LeftShift(Result[I-1].D,DES_LSH[I-1]);
End;
End;
Function GetConcatKey(Key:TSplitKey):TConcatKey;
Var
I:Integer;
Temp:TBitString;
Begin
For I:=0 To 15 Do
Begin
SetLength(Result[I],56);
Temp:=ConcatBits([Key[I+1].C,Key[I+1].D]);
Result[I]:=GetPermutedKey2(Temp);
End;
End;
Function GetIPKey(M:TBitString; ConcatKey:TConcatKey):TIPKey;
Var
I,J:Integer;
IP, F:TBitString;
Begin
For I:=0 To 16 Do
Begin
SetLength(Result[I].L,32);
SetLength(Result[I].R,32);
End;
SetLength(IP,64);
For I:=0 To Length(DES_IP)-1 Do
IP[I]:=M[DES_IP[I]-1];
For I:=0 To 31 Do
Result[0].L[I]:=IP[I];
For I:=32 To 63 Do
Result[0].R[I-32]:=IP[I];
For I:=1 To 16 Do
Begin
Result[I].L:=Result[I-1].R;
F:=GetF(Result[I-1].R,ConcatKey[I-1]);
For J:=0 To 31 Do
Result[I].R[J]:=Result[I-1].L[J] XOR F[J];
End;
End;
Function GetF(R,K:TBitString):TBitString;
Var
I,J:Integer;
S,E,KE,F,T:TBitString;
Begin
SetLength(E,48);
For I:=0 To 47 Do
E[I]:=R[DES_E[I]-1];
SetLength(KE,48);
For I:=0 To 47 Do
KE[I]:=K[I] XOR E[I];
SetLength(T,6);
SetLength(F,0);
SetLength(S,4);
I:=0;
While I<48 Do
Begin
For J:=0 To 6 Do
T[J]:=KE[J+I];
S:=GetSBox(I div 6,T);
F:=ConcatBits([F,S]);
I:=I+6;
End;
SetLength(Result,32);
For I:=0 To 31 Do
Result[I]:=F[DES_P[I]-1];
End;
Function GetSBox(Index:Integer; T:TBitString):TBitString;
Var
Val,Row,Col:Integer;
Temp:TBitString;
Begin
SetLength(Result,4);
SetLength(Temp,2);
Temp[0]:=T[0];
Temp[1]:=T[5];
Row:=BinToInt(Temp);
SetLength(Temp,4);
CopyBits(Temp,TBitString(@T[1]),4);
Col:=BinToInt(Temp);
Val:=S_BOXES[Index,Row,Col];
SetLength(Result,4);
Result:=IntToBin(Val,4);
End;
Function GetReverseIP(RL:TBitString):TBitString;
Var
I:Integer;
Begin
SetLength(Result,64);
For I:=0 To Length(DES_REVERSE_IP)-1 Do
Result[I]:=RL[DES_REVERSE_IP[I]-1];
End;
Procedure ReverseSubKeys(Var Keys:TConcatKey);
Var
I,L:Integer;
T:TBitString;
Begin
SetLength(T,48);
L:=Length(Keys);
For I:=0 To (L-1)Div 2 Do
Begin
T:=Keys[I];
Keys[I]:=Keys[(L-I)-1];
Keys[(L-I)-1]:=T;
End;
End;
Function DESEncode(S,Key:String):TBitString;
Var
I:Integer;
K:TBitString;
M:TBitString;
RL:TBitString;
Kplus:TBitString;
SplitKey:TSplitKey;
ConcatKey:TConcatKey;
IPKey:TIPKey;
Begin
K:=AnsiStrToBin(Key);
Kplus:=GetPermutedKey(K);
SplitKey:=GetSplitKey(Kplus);
ConcatKey:=GetConcatKey(SplitKey);
M:=AnsiStrToBin(S);
IPKey:=GetIPKey(M,ConcatKey);
SetLength(RL,64);
For I:=0 To 31 Do
Begin
RL[I]:=IPKey[16].R[I];
RL[I+32]:=IPKey[16].L[I];
End;
RL:=GetReverseIP(RL);
Result:=RL;
End;
Function DESDecode(S,Key:String):TBitString;
Var
I:Integer;
K:TBitString;
M:TBitString;
RL:TBitString;
Kplus:TBitString;
SplitKey:TSplitKey;
ConcatKey:TConcatKey;
IPKey:TIPKey;
Begin
K:=AnsiStrToBin(Key);
Kplus:=GetPermutedKey(K);
SplitKey:=GetSplitKey(Kplus);
ConcatKey:=GetConcatKey(SplitKey);
ReverseSubKeys(ConcatKey);
M:=AnsiStrToBin(S);
IPKey:=GetIPKey(M,ConcatKey);
SetLength(RL,64);
For I:=0 To 31 Do
Begin
RL[I]:=IPKey[16].R[I];
RL[I+32]:=IPKey[16].L[I];
End;
RL:=GetReverseIP(RL);
Result:=RL;
End;
end.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -