📄 新建 文本文档 (3).txt
字号:
REPNE SCASB;
MOV EAX, ECX;
CLD;
JE @FOUND;
MOV EAX, -1;
@FOUND:
POP EDI;
end;
procedure TDesEncryptor.SetKey(theKey: String);
begin
Key := theKey;
MakeKeyData;
end;
procedure TDesEncryptor.DecodeVar(var Data: OleVariant);
var
DataBits: array [0..63] of Byte;
Level: Integer;
ptrData: PByteArray;
I, DataSize, NewDataSize: Integer;
begin
Level := 16;
DataSize := VarArrayHighBound(Data, 1) - VarArrayLowBound(Data, 1) + 1;
if DataSize mod 8 <> 0 then
begin
DataSize := (DataSize Div 8) * 8;
VarArrayRedim(Data, DataSize + VarArrayLowBound(Data, 1) - 1);
end;
ptrData := VarArrayLock(Data);
try
I:= 0;
while (I < DataSize) do
begin
GetBits(ptrData^[I], DataBits, 8);
UNDES(DataBits, KeyData[0], Level);
SetBits(DataBits, ptrData^[I], 8);
Inc(I, 8);
end;
NewDataSize := FindByteBack($FF, PtrData[0], DataSize);
finally
VarArrayUnlock(Data);
end;
if NewDataSize < 0 then
raise EDesError.CreateRes(@SErrorDesBadcryptograph);
VarArrayRedim(Data, NewDataSize + VarArrayLowBound(Data, 1) - 1);
end;
procedure TDesEncryptor.EncodeVar(var Data: OleVariant);
var
DataBits: array [0..63] of Byte;
Level: Integer;
ptrData: PByteArray;
I, DataSize, OldDataSize: Integer;
begin
Level := 16;
DataSize := VarArrayHighBound(Data, 1) - VarArrayLowBound(Data, 1) + 1;
OldDataSize := DataSize;
DataSize := (DataSize Div 8 +1) * 8;
VarArrayRedim(Data, DataSize - VarArrayLowBound(Data, 1) - 1);
ptrData := VarArrayLock(Data);
try
ptrData[OldDataSize] := $FF;
for I := OldDataSize + 1 to DataSize - 1 do
ptrData[I] := Random(255);
I:= 0;
while (I < DataSize) do
begin
GetBits(ptrData^[I], DataBits, 8);
DES(DataBits, KeyData[0], Level);
SetBits(DataBits, ptrData^[I], 8);
Inc(I, 8);
end;
finally
VarArrayUnlock(Data);
end;
end;
procedure TDesEncryptor.Decode(const InStream, OutStream: TStream);
const
BlockSize = 1024;
bBlockSize = BlockSize * 8;
var
DataBits: array[0..63] of Byte;
Data: array [0..BlockSize-1, 0..7] of Byte;
Level: Integer;
InSize, Progress, ReadPos, WritePos, SizeOfHoleBlock: Int64;
LastBlockSize, ProgressInBlock: Integer;
begin
Level := 16;
InSize := InStream.Size;
InStream.Position := 0;
OutStream.Position := 0;
Progress := 0;
ReadPos := 0;
WritePos := 0;
SizeOfHoleBlock := ((InSize - 1) div BlockSize) * BlockSize;
while Progress < SizeOfHoleBlock do
begin
InStream.Position := ReadPos;
InStream.Read(Data[0,0], bBlockSize);
for ProgressInBlock := 0 to BlockSize - 1 do
begin
GetBits(Data[ProgressInBlock,0], DataBits, 8);
UNDES(DataBits, KeyData[0], Level);
SetBits(DataBits, Data[ProgressInBlock,0], 8);
end;
OutStream.Position := WritePos;
OutStream.Write(Data[0,0], bBlockSize);
Inc(ReadPos, bBlockSize);
Inc(WritePos, bBlockSize);
Inc(Progress, bBlocksize);
end;
InSize := InSize - SizeOfHoleBlock;
InStream.Position := ReadPos;
InStream.Read(Data, InSize);
LastBlockSize := InSize div 8;
InSize := LastBlockSize * 8;
for ProgressInBlock := 0 to LastBlockSize - 1 do
begin
GetBits(Data[ProgressInBlock,0], DataBits, 8);
UNDES(DataBits, KeyData[0], Level);
SetBits(DataBits, Data[ProgressInBlock,0], 8);
end;
InSize := FindByteBack($FF, Data, InSize);
if InSize < 0 then
raise EDesError.CreateRes(@SErrorDesBadcryptograph);
OutStream.Position := WritePos;
OutStream.Write(Data[0,0], InSize);
OutStream.Size := OutStream.Position;
end;
procedure TDesEncryptor.Encode(const InStream, OutStream: TStream);
const
BlockSize = 1024;
bBlockSize = BlockSize * 8;
var
DataBits: array [0..63] of Byte;
Data: array [0..BlockSize-1, 0..7] of Byte;
Level: Integer;
InSize, Progress, ReadPos, WritePos, SizeOfHoleBlock: Int64;
LastBlockSize, ProgressInBlock: Integer;
I: Integer;
begin
Level := 16;
InSize := InStream.Size;
InStream.Position := 0;
OutStream.Position := 0;
Progress := 0;
ReadPos := 0;
WritePos := 0;
SizeOfHoleBlock := InSize - InSize mod bBlockSize;
while Progress < SizeOfHoleBlock do
begin
InStream.Position := ReadPos;
InStream.Read(Data[0,0], bBlockSize);
for ProgressInBlock := 0 to BlockSize - 1 do
begin
GetBits(Data[ProgressInBlock,0], DataBits, 8);
DES(DataBits, KeyData[0], Level);
SetBits(DataBits, Data[ProgressInBlock,0], 8);
end;
OutStream.Position := WritePos;
OutStream.Write(Data[0,0], bBlockSize);
Inc(ReadPos, bBlockSize);
Inc(WritePos, bBlockSize);
Inc(Progress, bBlocksize);
end;
InSize := InSize mod bBlockSize;
InStream.Position := ReadPos;
InStream.Read(Data, InSize);
LastBlockSize := InSize div 8 + 1;
PByteAry(@Data)^[InSize] := $FF;
for I := InSize + 1 to LastBlockSize * 8 - 1 do
PByteAry(@Data)^[I] := Random(255);
for ProgressInBlock := 0 to LastBlockSize - 1 do
begin
GetBits(Data[ProgressInBlock,0], DataBits, 8);
DES(DataBits, KeyData[0], Level);
SetBits(DataBits, Data[ProgressInBlock,0], 8);
end;
OutStream.Position := WritePos;
OutStream.Write(Data[0,0], LastBlockSize * 8);
OutStream.Size := SizeOfHoleBlock + LastBlockSize * 8;
end;
procedure TDesEncryptor.MakeKeyData;
const
KeySuffixes: array [0..5] of String =
('dsafsda',
'rerwawe',
'32522asf',
',.[[]-\',
'`2304-`',
'va[0e324');
var
PackedKeyData: array[0..95] of Byte;
Temp: String;
I: Integer;
begin
for I := 0 to 5 do
begin
Temp := Key + KeySuffixes[I];
MD5Code(Temp[1], PackedKeyData[I *16], Length(Temp));
end;
for I := 0 to 15 do
GetBits(PackedKeyData[I*6], KeyData[I], 6);
end;
destructor TDesEncryptor.Destroy;
begin
inherited;
end;
constructor TDesEncryptor.Create;
begin
inherited Create;
SetKey('')
end;
function TDesEncryptor.DecodeMem(var Data; DataSize: Integer): Integer;
var
DataBits: array [0..63] of Byte;
Level: Integer;
ptrData: PByteArray;
I: Integer;
begin
Level := 16;
if DataSize mod 8 <> 0 then
begin
DataSize := (DataSize Div 8) * 8;
end;
ptrData := @Data;
I:= 0;
while (I < DataSize) do
begin
GetBits(ptrData^[I], DataBits, 8);
UNDES(DataBits, KeyData[0], Level);
SetBits(DataBits, ptrData^[I], 8);
Inc(I, 8);
end;
Result := FindByteBack($FF, Data, DataSize);
if Result < 0 then
raise EDesError.CreateRes(@SErrorDesBadcryptograph);
end;
function TDesEncryptor.EncodeMem(var Data; DataSize: Integer): Integer;
var
DataBits: array [0..63] of Byte;
Level: Integer;
ptrData: PByteArray;
I, OldDataSize: Integer;
begin
Level := 16;
OldDataSize := DataSize;
DataSize := (DataSize Div 8 + 1) * 8;
ptrData :=@Data;
PtrData[OldDataSize] := $FF;
for I := OldDataSize + 1 to DataSize - 1 do
PtrData[I] := Random(255);
I:= 0;
while (I < DataSize) do
begin
GetBits(ptrData^[I], DataBits, 8);
DES(DataBits, KeyData[0], Level);
SetBits(DataBits, ptrData^[I], 8);
Inc(I, 8);
end;
Result := DataSize;
end;
function TDesEncryptor.GetMaxDecodeSize(DataSize: Integer): Integer;
begin
Result := DataSize;
end;
function TDesEncryptor.GetMaxEncodeSize(DataSize: Integer): Integer;
begin
Result := ((DataSize + 1) div 8 + 1) * 8;
end;
initialization
Randomize;
end.
由于DES加密是以64位(8字节)为单位的,加密前必须把明文长度调整为8字节的整数倍。为了能够在解密时知道明文的准确长度,加密前在明文末尾追加加了一个#$FF,然后用不等于#$FF的随机数填充到8字节整数倍。在解密后从明文末尾向前查找第一个#$FF,从而确定明文的准确长度。
下面是对字符串加密和对文件加密的测试(Delphi 6):
//Unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
btnTestStr: TButton;
edtKey: TLabeledEdit;
edtPlain: TLabeledEdit;
edtCipher: TLabeledEdit;
edtDecrypted: TLabeledEdit;
btnEncryptfile: TButton;
btnDecryptfile: TButton;
dlgOpen: TOpenDialog;
dlgSave: TSaveDialog;
procedure btnTestStrClick(Sender: TObject);
procedure btnDecryptFileClick(Sender: TObject);
procedure btnEncryptFileClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
DesEncryptor;
{$R *.dfm}
procedure TForm1.btnTestStrClick(Sender: TObject);
var
Temp: String;
Encryptor: TDesEncryptor;
L: Integer;
Printable: String;
begin
Encryptor := TDesEncryptor.Create;
try
Encryptor.SetKey(edtKey.Text);
Temp := edtPlain.Text;
//加密
L := Length(Temp);
SetLength(Temp, Encryptor.GetMaxEncodeSize(Length(Temp)));
L := Encryptor.EncodeMem(Temp[1], L);
SetLength(Temp, L);
//显示密文(因为密文不是ASCII码,要转换一下才能显示)
SetLength(Printable, L *2);
BinToHex(PChar(Temp), PChar(Printable), L);
edtCipher.Text := Printable;
//解密
L := Length(Temp);
SetLength(Temp, Encryptor.GetMaxDecodeSize(L));
L := Encryptor.DecodeMem(Temp[1], L);
SetLength(Temp, L);
edtDecrypted.Text := Temp;
finally
Encryptor.Free;
end;
end;
procedure TForm1.btnDecryptFileClick(Sender: TObject);
var
InStrm, OutStrm: TStream;
Encryptor: TDesEncryptor;
begin
InStrm := nil;
OutStrm := nil;
Encryptor := nil;
try
if dlgOpen.Execute and dlgSave.Execute then
begin
InStrm :=TFileStream.Create(dlgOpen.FileName, fmOpenRead);
OutStrm := TFileStream.Create(dlgSave.FileName,fmCreate);
Encryptor := TDesEncryptor.Create;
Encryptor.SetKey(edtKey.Text);
Encryptor.Decode(InStrm, OutStrm);
end;
finally
InStrm.Free;
OutStrm.Free;
Encryptor.Free;
end;
end;
procedure TForm1.btnEncryptFileClick(Sender: TObject);
var
InStrm, OutStrm: TStream;
Encryptor: TDesEncryptor;
begin
InStrm := nil;
OutStrm := nil;
Encryptor := nil;
try
if dlgOpen.Execute and dlgSave.Execute then
begin
InStrm :=TFileStream.Create(dlgOpen.FileName, fmOpenRead);
OutStrm := TFileStream.Create(dlgSave.FileName,fmCreate);
Encryptor := TDesEncryptor.Create;
Encryptor.SetKey(edtKey.Text);
Encryptor.Encode(InStrm, OutStrm);
end;
finally
InStrm.Free;
OutStrm.Free;
Encryptor.Free;
end;
end;
end.
//Unit1.dfm
object Form1: TForm1
Left = 222
Top = 147
Width = 432
Height = 167
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object btnTestStr: TButton
Left = 8
Top = 8
Width = 75
Height = 25
Caption = '字符串测试'
TabOrder = 0
onClick = btnTestStrClick
end
object edtKey: TLabeledEdit
Left = 120
Top = 8
Width = 297
Height = 21
EditLabel.Width = 24
EditLabel.Height = 13
EditLabel.Caption = '密钥'
LabelPosition = lpLeft
LabelSpacing = 3
TabOrder = 1
end
object edtPlain: TLabeledEdit
Left = 120
Top = 40
Width = 297
Height = 21
EditLabel.Width = 24
EditLabel.Height = 13
EditLabel.Caption = '明文'
LabelPosition = lpLeft
LabelSpacing = 3
TabOrder = 2
end
object edtCipher: TLabeledEdit
Left = 120
Top = 72
Width = 297
Height = 21
EditLabel.Width = 24
EditLabel.Height = 13
EditLabel.Caption = '密文'
LabelPosition = lpLeft
LabelSpacing = 3
TabOrder = 3
end
object edtDecrypted: TLabeledEdit
Left = 120
Top = 104
Width = 297
Height = 21
EditLabel.Width = 24
EditLabel.Height = 13
EditLabel.Caption = '解密'
LabelPosition = lpLeft
LabelSpacing = 3
TabOrder = 4
end
object btnEncryptfile: TButton
Left = 8
Top = 40
Width = 75
Height = 25
Caption = '加密文件'
TabOrder = 5
onClick = btnEncryptFileClick
end
object btnDecryptfile: TButton
Left = 8
Top = 72
Width = 75
Height = 25
Caption = '解密文件'
TabOrder = 6
onClick = btnDecryptFileClick
end
object dlgOpen: TOpenDialog
Left = 16
Top = 104
end
object dlgSave: TSaveDialog
Left = 48
Top = 104
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -