📄 mianunit.~pas
字号:
Result:=f;
end;
function TForm1.OcttoBin(i: integer): string; //十进制转换为二进制字符串
var
j,k: integer;
s: string;
begin
j := i;
s := '';
while j >= 2 do
begin
if (j mod 2) = 1 then
begin
s := '1' + s;
j := j div 2;
end
else
begin
s := '0' + s;
j := j div 2;
end;
end;
s := chr(ord('0') + j) + s;
if length(s)<4 then
for k:=1 to 4-length(s) do
s:='0'+s;
result := s;
end;
function TForm1.CnBinToInt(k: string): integer; //二进制字符串转换为十进制
var
i, j, t: integer;
s: char;
begin
t := 1;
j := length(k);
j := 0 + (ord(k[j]) - ord('0')) * t;
;
for i := length(k) - 1 downto 1 do
begin
s := k[i];
t := t * 2;
j := j + ((ord(s) - ord('0')) * t);
end;
result := j;
end;
function TForm1.XORXY(x:string;y:string):string;//两个数异或函数
var
i,len:integer;
begin
len:=length(x);
Result := '';
for i:=1 to len do
if copy(x,i,1)=copy(y,i,1) then
Result:=Result+'0'
else
Result:=Result+'1';
end;
function TForm1.rPZH(r:string):string;//P置换函数
var
i:integer;
begin
Result:='';
for i:=1 to 32 do
Result:=Result+r[PZH[i]];
end;
procedure TForm1.Button1Click(Sender: TObject); //加密
var
input,input1,a,a1,my,b,m,m1,C,D,L,R,x,y,z,code:string;
i,j,k,n:integer;
Mc,Md,ZIMY,AL,AR:array[1..16] of string;
begin
memo2.Text :='';
memo3.Text :='';
input:=memo1.Text ;
input1:='';
i:=1;
while i<= length(input) do //判断输入字符,用一个while循环
begin
if ord(input[i])<127 then //如果输入字符的Ascii码值小于127(33-126为键盘可使用字符)
begin
input1:=input1+input[i]; //input1添加一个字符
i:=i+1;
end
else //如果大于等于127
begin
if (length(input1) mod 8 = 7) and (ord(input[i+1])>126) then //如果此时input1的长度为7(即二进制长度为56),并且第八位的Ascii码值大于126
input1 :=input1+chr(0)+input[i]+input[i+1] //则input1加上一个NUL(ascii码为00000000,解密时不显示),再加上后面的两位,即一个汉字
else
input1:=input1+input[i]+input[i+1]; //不是,则直接加上后面的两位:一个汉字
i:=i+2;
end;
end;
if length(input1) mod 8 <> 0 then //如果输入不是8的倍数,则在最后补NUL
begin
for i:= 1 to 8 - (length(input1) mod 8) do
input1:=input1+chr(0);
end;
a1:=ConvertStrToBin(input1); //把补齐后的明文转换为二进制
my:=edit1.Text;
if length(my)<8 then //得到密钥长度
begin
for i:= 1 to 8 - length(my) do //如果小于8位,在密钥后面补x
my:=my+'x';
end
else //如果超过8位,则取前8位
m:=copy(my,1,8);
m:=ConvertStrToBin(my); //把密钥转换为64二进制
b:=''; L:='';R:='';
m1:='';C:='';d:='';
x:='';
//得到16个子密钥
begin
j:=1;
while j<=56 do //取56位密钥并进行56位密钥置换
begin
m1:=m1+m[MYZH[j]];
j:=j+1;
end;
for j:=1 to 56 do //把密钥分成两部分C,D,每部分28位
begin
if j<=28 then
C:=C+m1[j]
else
D:=D+m1[j];
end;
for j:=2 to 16 do //得到C、D每一次移位的值,分别放在数组Mc、Md中
begin
Mc[1]:=LMove(c,1);Md[1]:= LMove(d,1);
if (j=2) or(j=9) or (j=16) then
begin
Mc[j]:=LMove(Mc[j-1],1);
Md[j]:=LMove(Md[j-1],1);
end
else
begin
Mc[j]:=LMove(Mc[j-1],2);
Md[j]:=LMove(Md[j-1],2);
end;
end;
for i:=1 to 16 do //得到16个48位的子密钥放在数组ZIMY中
ZIMY[i]:=ZMYChange(Mc[i],Md[i]);
end;
n:=length(a1) div 64; //把明文分成n等份,每份64位
for k:=1 to n do //从1到64开始循环加密
begin
i:=1;b:='';
a:=copy(a1,(k-1)*64+1,64); //从明文中循环逐一取出64位
while i<=64 do //初始明文置换
begin
b:=b+a[ZH[i]];
i:=i+1;
end;
L:='';R:='';
for i:=1 to 64 do //得到32位的L和R
begin
if i<=32 then
L:=L+b[i]
else
R:=R+b[i];
end;
AL[1]:=R;
x:= LiRi(XORXY(KZR(R),ZIMY[1]));//R ,K 异或
y:=rPZH(x);//把R ,K 异或后再用P置换
AR[1]:=XORXY(L,y);
for i:=2 to 16 do //16次迭代过程
begin
AL[i]:=AR[i-1]; //Li=Ri-1
AR[i]:=XORXY(AL[i-1],rPZH(LiRi(XORXY(KZR(AR[i-1]),ZIMY[i])))); //Ri=Li-1 xor f(Ri-1,Ki)
end;
z:=AL[16]+AR[16]; //得到16次迭代后的64位二进制数
code:='';
for i:=1 to 64 do //经过逆置换得到二进制密文
code:=code+z[NZH[i]];
memo2.Text:=memo2.Text+code;//memo2.Text+ConvertBinToStr(code);
end;
end;
procedure TForm1.Button2Click(Sender: TObject); //解密
var
a,a1,my,b,m,m1,C,D,L,R,L0,R0,x,z,uncode:string;
i,j,k,n:integer;
Mc,Md,ZIMY,AL,AR:array[1..16] of string;
begin
memo3.Text :='';
a1:=memo2.text;//ConvertStrToBin(Memo2.Text);
my:=edit1.Text;
if length(my)<8 then //得到密钥长度
begin
for i:= 1 to 8 - length(my) do //如果小于8位,在密钥后面补x
my:=my+'x';
end
else
m:=copy(my,1,8); //如果超过8位,则取前8位
m:=ConvertStrToBin(my); //把密钥转换为64二进制
b:=''; L:='';R:='';
m1:='';C:='';d:='';
j:=1;x:='';
begin
while j<=56 do //取56位密钥并进行56位密钥置换
begin
m1:=m1+m[MYZH[j]];
j:=j+1;
end;
for j:=1 to 56 do //把密钥分成两部分C,D,每部分28位
begin
if j<=28 then
C:=C+m1[j]
else
D:=D+m1[j];
end;
for j:=2 to 16 do //得到C、D每一次移位的值,分别放在数组Mc、Md中
begin
Mc[1]:=LMove(c,1);Md[1]:= LMove(d,1);
if (j=2) or(j=9) or (j=16) then //如果是第1、2、9、16次移位,则移一位
begin
Mc[j]:=LMove(Mc[j-1],1);
Md[j]:=LMove(Md[j-1],1);
end
else //如果不是就移两位
begin
Mc[j]:=LMove(Mc[j-1],2);
Md[j]:=LMove(Md[j-1],2);
end;
end;
for i:=1 to 16 do //得到16个48位的子密钥放在数组ZIMY中
ZIMY[i]:=ZMYChange(Mc[i],Md[i]);
end;
n:=length(a1) div 64; //把密文分段
for k:=1 to n do
begin
i:=1;b:=''; //把i置1
a:=copy(a1,(k-1)*64+1,64); //每64位循环取a进行加密
while i<=64 do //初始密文置换
begin
b:=b+a[ZH[i]];
i:=i+1;
end;
L:='';R:='';
for i:=1 to 64 do //得到32位的L和R
begin
if i<=32 then
L:=L+b[i]
else
R:=R+b[i];
end;
AR[16]:=R;
AL[16]:=L;
for i:=16 downto 2 do //16次迭代过程,是加密的逆过程,i从16到1逆着解密
begin
AR[i-1]:=AL[i]; //Ri=Li+1
AL[i-1]:=XORXY(AR[i],rPZH(LiRi(XORXY(KZR(AL[i]),ZIMY[i])))); //Li=Ri+1 xor f(Li+1,Ki)
end;
R0:=AL[1]; //得到明文的二进制R和L
L0:=XORXY(AR[1],rPZH(LiRi(XORXY(KZR(AL[1]),ZIMY[1]))));
z:=L0+R0; //把L和R相加得到明文的二进制
uncode:='';
for i:=1 to 64 do //经过逆置换得到明文
uncode:=uncode+z[NZH[i]];
memo3.Text:=memo3.Text+ConvertBinToStr(uncode); //经过函数转换把明文二进制解密为明文
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
form2.Show;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
memo1.Text :='';
memo2.Text :='';
memo3.Text :='';
edit1.Text :='';
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
form3.Show;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -