📄 unit1.pas
字号:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,Math;
// initial permutation (IP) 数据处理IP置换
const
IP_Table :array[0..63]of Integer =(
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);
PC1_Table:array[0..55]of Integer = (
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
Shift_Table:array[0..15]of Integer = (
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1);
// permuted choice key (PC2)
PC2_Table:array[0..47]of Integer = (
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);
// expansion operation matrix (E)
E_Table:array[0..47]of Integer =(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);
// final permutation IP^-1
IPR_Table:array[0..63]of Char =(
Char(40), Char(8), Char(48), Char(16), Char(56), Char(24), Char(64), Char(32), Char(39),
Char(7), Char(47), Char(15), Char(55), Char(23), Char(63), Char(31),Char(38), Char(6),
Char(46), Char(14), Char(54), Char(22), Char(62), Char(30), Char(37), Char(5), Char(45),
Char(13), Char(53), Char(21), Char(61), Char(29), Char(36), Char(4), Char(44), Char(12),
Char(52), Char(20), Char(60), Char(28), Char(35), Char(3), Char(43), Char(11), Char(51),
Char(19), Char(59), Char(27), Char(34), Char(2), Char(42), Char(10), Char(50), Char(18),
Char(58), Char(26), Char(33), Char(1), Char(41), Char(9), Char(49), Char(17), Char(57), Char(25));
// 32-bit permutation function P used on the output of the S-boxes
P_Table:array[0..31]of Char = (
Char(16), Char(7), Char(20), Char(21), Char(29), Char(12), Char(28),
Char(17), Char(1), Char(15), Char(23), Char(26), Char(5), Char(18),
Char(31), Char(10), Char(2), Char(8), Char(24), Char(14), Char(32),
Char(27), Char(3), Char(9), Char(19), Char(13), Char(30), Char(6),
Char(22), Char(11), Char(4), Char(25));
// The (in)famous S-boxes
S_Box:array[0..7]of array[0..3,0..15]of Integer = (
//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)));
type
TSubKey = array[0..15,0..47]of Char;
type
TForm1 = class(TForm)
btn1: TButton;
edt2: TEdit;
lbl1: TLabel;
edt3: TEdit;
lbl2: TLabel;
lbl3: TLabel;
btn4: TButton;
edt4: TEdit;
lbl4: TLabel;
lbl5: TLabel;
btn2: TButton;
edt1: TEdit;
lbl6: TLabel;
btn3: TButton;
edt5: TEdit;
btn5: TButton;
procedure btn1Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
procedure btn4Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure btn5Click(Sender: TObject);
private
{ Private declarations }
SubKeys:TSubKey; //array[0..15,0..47]of Char;//储存16组48位密钥
SubKeys2:TSubKey;//array[0..15,0..47]of Char;//储存16组48位密钥
szCiphertext:array[0..15]of Char;//储存16位密文(十六进制字符串)
szPlaintext:array[0..7]of Char;//储存8位明文字符串
szFCiphertextAnyLength:array[0..8191]of Char;//任意长度密文(十六进制字符串)
szFPlaintextAnyLength:array[0..4095]of Char;//任意长度明文字符串
// szFPlaintextAnyLength:array[0..4095]of Char ;//任意长度明文字符串
function FillToEightBits(var sz:string):Boolean;
function SingleBinaryToChar(iTmp:Integer):Char;
function SingleCharToBinary(ch:Char):Integer;
function CreateSubKey(sz:array of Char;var reSubKey:TSubKey):Boolean;
function EncryptAnyLength(szSource:string;bIsUseSecondKey:Boolean):Boolean;
function EncryptData(s:string;bIsUseSecondKey,bShowResultInHex:Boolean):Boolean;
function GetCiphertextAnyLength:string;
function InitialPermuteData(s:string;var sz:array of Char;szBool:Boolean):Boolean;
//--------------------------------------------------------------
//功能:DES中的F函数,
//参数:左32位,右32位,key序号(0-15)
//结果:均在变换左右32位
//--------------------------------------------------------------
procedure FunctionF(var sz_Li1, sz_Ri1:array of Char;bIsUseSecondKey:Boolean;iKey:Integer);
//--------------------------------------------------------------
//功能:将右32位进行扩展位48位,
//参数:原32位字符串,扩展后结果存放指针
//结果:函数改变第二个参数的内容
//--------------------------------------------------------------
procedure ExpansionR(var rsData,deData:array of Char);
//--------------------------------------------------------------
//功能:异或函数,
//参数:待异或的操作字符串1,字符串2,操作数长度,处理后结果存放指针
//结果: 函数改变第四个参数的内容
//--------------------------------------------------------------
procedure ExecXOR(sz_P1,sz_P2:array of Char;len:Integer; var Return_value:array of Char);
//--------------------------------------------------------------
//功能:S-BOX , 数据压缩,
//参数:48位二进制字符串,
//结果:返回结果:32位字符串
//--------------------------------------------------------------
function CompressFuncS(sz_48:array of Char):string;
//--------------------------------------------------------------
//功能:IP逆变换,
//参数:待变换字符串,处理后结果存放指针
//结果:函数改变第二个参数的内容
//--------------------------------------------------------------
procedure PermutationP(s:string;var Return_value:array of Char);
//--------------------------------------------------------------
//功能:16进制整数(0-15)到2进制字符串的转换
//参数:十六进制整数(0-15)
//结果:返回二进制字符串("0000"-"1111")
//--------------------------------------------------------------
function HexIntToBinary(i:Integer ):string;
function MyPower(base,Exponent:Integer):Integer;
//--------------------------------------------------------------
//功能:二进制串到字符串的转换,
//参数:源二进制字符串,二进制字符串长度,类型(true为二进制到hex,false为二进制到ANSCII char),
//结果:返回处理后结果
//--------------------------------------------------------------
function BinaryToString(szSource:array of Char; len:Integer;bType:Boolean):string;
//--------------------------------------------------------------
//功能:解密任意长度十六进制字符串
//参数:任意长度字符串
//结果:函数将加密后结果存放于private szFPlaintextAnyLength[4096]
// 用户通过属性PlaintextAnyLength得到
//--------------------------------------------------------------
function DecryptAnyLength( sHexData:string;bIsUseSecondKey:Boolean):Boolean;
//--------------------------------------------------------------
//功能:解密16位十六进制字符串
//参数:16位十六进制字符串
//结果:函数将解密候结果存放于private szPlaintext[8]
// 用户通过属性Plaintext得到
//--------------------------------------------------------------
function DecryptData(s:string;bIsUseSecondKey,bDecryptHex:Boolean):Boolean;
function HexCharToBinary(ch:Char):string;
//--------------------------------------------------------------
//功能:使用3DES加密任意长度字符串
//参数:任意长度字符串
//结果:函数将加密后结果存放于private szFCiphertextAnyLength[8192]
// 用户通过属性CiphertextAnyLength得到
//--------------------------------------------------------------
procedure TripleEncryptAnyLength(szSource:string);
//--------------------------------------------------------------
//功能:使用3DES解密任意长度十六进制字符串
//参数:任意长度字符串
//结果:函数将加密后结果存放于private szFPlaintextAnyLength[4096]
// 用户通过属性PlaintextAnyLength得到
//--------------------------------------------------------------
procedure TripleDecryptAnyLength(szSource:string);
public
{ Public declarations }
procedure InitializeKey(sKey:string;isScndKey:Boolean); //处理密钥
end;
var
Form1: TForm1;
implementation
uses Des3DesPrg;
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
begin
edt4.Text := '';
FillChar(SubKeys,SizeOf(SubKeys),$0);
FillChar(SubKeys2,SizeOf(SubKeys2),$0);
InitializeKey(Trim(edt1.Text),False); //变换密钥
EncryptAnyLength(Trim(edt3.Text),False);
edt5.Text :=GetCiphertextAnyLength();
end;
function TForm1.SingleBinaryToChar(iTmp:Integer): Char;
begin
if iTmp=1 then
Result:= '1'
else
Result:='0';
end;
procedure TForm1.btn3Click(Sender: TObject);
begin
TripleDecryptAnyLength(edt5.Text);
edt4.Text := szFPlaintextAnyLength;
end;
procedure TForm1.InitializeKey(sKey: string;isScndKey:Boolean);
var
sz_64key:array[0..63]of Char;
iTmpBit:array[0..63]of Integer;
sz_56Key:array[0..55]of Char;
i,j,it:Integer;
begin
FillChar(iTmpBit,SizeOf(iTmpBit),0);
FillChar(sz_64key,SizeOf(sz_64key),' ');
FillChar(sz_56Key,SizeOf(sz_56Key),' ');
//convert 8 char-bytes key to 64 binary-bits 把8字节的密钥转换为64位的二进制bits
for i:=0 to 63 do
begin
it := i shr 3;
if it<Length(sKey) then
iTmpBit[i] := (Ord(sKey[it+1])shr(i and 7))and 1
else
iTmpBit[i] := 0;
//a = 0x61 = 0110,0001
//after this , a is 1000,0110
end;
// let me convert it to right
for i:=0 to 7 do
begin
for j:=0 to 7 do
sz_64key[8*i+j] := SingleBinaryToChar(iTmpBit[8*(i+1)-(j+1)]);
end;
// 舍弃64位密钥中的奇偶校验位,然后按PC1置换
for i:=0 to 55 do
begin
sz_56Key[i] := sz_64key[PC1_Table[i]-1];
end;
if isScndKey then
CreateSubKey(sz_56Key,SubKeys2)
else
CreateSubKey(sz_56Key,SubKeys);
end;
function TForm1.CreateSubKey(sz:array of Char;var reSubKey:TSubKey): Boolean;
var
szCi,szDi,szTmpR,szTmpL:array[0..27] of Char;
szTmp56:array[0..55] of Char;
i,j:Integer;
begin
FillChar(szTmpL,SizeOf(szTmpL),$0);
FillChar(szTmpR,SizeOf(szTmpR),$0);
FillChar(szCi,SizeOf(szCi),$0);
FillChar(szDi,SizeOf(szDi),$0);
//把56位密钥分解为两部分
CopyMemory(@szTmpL[0],@sz[0],28);
CopyMemory(@szTmpR[0],@sz[28],28);
{生成16个子密钥,初始I=1。
1-2-3-1、同时将C[I]、D[I]左移1位或2位,根据I值决定左移的位数。见下表
I: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
左移位数: 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1}
for i:=0 to 15 do
begin
//shift to left
//Left 28 bits
CopyMemory(@szCi,@szTmpL[Shift_Table[i]],28-Shift_Table[i]);
CopyMemory(@szCi[28-Shift_Table[i]],@szTmpL,Shift_Table[i]);
//Right 28 bits
CopyMemory(@szDi,@szTmpR[Shift_Table[i]],28 - Shift_Table[i]);
CopyMemory(@szDi[28 - Shift_Table[i]],@szTmpR,Shift_Table[i]);
//permuted choice 48 bits key
CopyMemory(@szTmp56,@szCi,28);
CopyMemory(@szTmp56[28],@szDi,28);
for j:=0 to 47 do
begin
reSubKey[i][j] := szTmp56[PC2_Table[j]-1]
end;
CopyMemory(@szTmpL,@szCi,28);
CopyMemory(@szTmpR,@szDi,28);
end;
Result := True;
end;
function TForm1.EncryptAnyLength(szSource: string;bIsUseSecondKey:Boolean): Boolean;
var
iLength,iParts,iResidue,i:Integer;
szLast8Bits,szTmp:string;
begin
iLength := Length(szSource);
if iLength = 8 then
begin
EncryptData(szSource,bIsUseSecondKey,true);
CopyMemory(@szFCiphertextAnyLength,@szCiphertext,16);
//set the last char to '\0'
szFCiphertextAnyLength[16] := Char($0);
end
else
if iLength<8 then
begin
FillToEightBits(szSource);
EncryptData(szSource,bIsUseSecondKey,true);
CopyMemory(@szFCiphertextAnyLength,@szCiphertext,16);
//set the last char to '\0'
szFCiphertextAnyLength[16] := Char($0);
end
else
if iLength>8 then
begin
iParts := ceil(iLength/8.0); //使用ceil函数。ceil(x)返回的是大于x的最小整数
iResidue := iLength mod 8;
//encrypt the data 8 by 8 except the last part
for i:=0 to (iParts-2) do
begin
szTmp := Copy(szSource,(i*8)+1,8);
EncryptData(szTmp,bIsUseSecondKey,true);
//after call EncryptData
//cpoy the temp result to szFCiphertextAnyLength
CopyMemory(@szFCiphertextAnyLength[16*i],@szCiphertext,16);
if iResidue<>0 then //can't be divided exactly by 8
begin
szLast8Bits := Copy(szSource,(iParts-1)*8+1,iResidue);
FillToEightBits(szLast8Bits);
end
else //be divided exactly by 8
szLast8Bits := Copy(szSource,(iParts-1)*8+1,8);
//encrypt the last part
EncryptData(szLast8Bits,bIsUseSecondKey,true);
CopyMemory(@szFCiphertextAnyLength[16*(iParts - 1)],@szCiphertext,16);
//set the last char to '\0'
szFCiphertextAnyLength[(iParts)*16] := Char($0);
end;
end;
Result := True;
end;
function TForm1.EncryptData(s: string;bIsUseSecondKey,bShowResultInHex:Boolean): Boolean;
var
iCnt:Integer;
sz_Li,sz_Ri:array[0..31] of Char;
sz_IP,sz_Final64,szCiphertextBinary:array[0..63] of Char;
begin
FillChar(sz_IP,SizeOf(sz_IP),$0);
FillChar(sz_Final64,SizeOf(sz_Final64),$0);
FillChar(szCiphertextBinary,SizeOf(szCiphertextBinary),$0);
//IP
InitialPermuteData(s,sz_IP,true);
//分成两部份
FillChar(sz_Li,SizeOf(sz_Li),$0);
FillChar(sz_Ri,SizeOf(sz_Ri),$0);
CopyMemory(@sz_Li[0],@sz_IP[0],32);
CopyMemory(@sz_Ri[0],@sz_IP[32],32);
for iCnt:=0 to 15 do
FunctionF(sz_Li,sz_Ri,bIsUseSecondKey,iCnt);
CopyMemory(@sz_Final64,@sz_Ri,32);
CopyMemory(@sz_Final64[32],@sz_Li,32);
//~IP
iCnt := 0;
// for iCnt := 0 to 63 do
while iCnt <64 do //按*P置换
begin
szCiphertextBinary[iCnt] := sz_Final64[Ord(IPR_Table[iCnt])-1];
Inc(iCnt);
end;
CopyMemory(@szCiphertext,PChar(BinaryToString(szCiphertextBinary,64,true)),16);
Result := True;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -