使用密码加密 .INI 文件字符串的简单代码 [英] Simple code to encrypt an .INI file string using a password
问题描述
我正在寻找比 ROT13 更复杂的东西,但它不需要库(最好甚至不需要一个单元,只是一个功能下降).
I am looking for something more sophisticated than ROT13, but which does not require a library (preferablly not even a unit, just a drop in function).
我想使用用户提供的密码对给定的字符串进行对称加密/解密.但是,结果必须是一个字符串,因为我必须能够将其存储在 .INI 文件中.
I want to symetrically encrypt/decrypt a given string with a password provided by the user. However, the result has to be a string, in the sense that it I have to be able to store it in an .INI file.
有没有人有一个简单的功能来做到这一点(delphi XE2)?Google 今天不是我的朋友.
Does anyone have a simple function to do this (delphi XE2)? Google is not my friend today.
提前致谢
[更新]/[赏金] 只是为了说明这一点(如果最初不是这样,请道歉),我不想要哈希值.我有一个列表框,用户可以在其中添加/修改/删除条目.我想在程序关闭时将它们存储在 .INI 文件中,并在再次启动时重新加载.任何查看 .INI 文件的人(例如,在记事本中打开它)都应该无法读取这些字符串.
[Update] / [Bounty] Just to make it clear (aplogies if it was not so originally), I don't want a hash. I have a list box where users can add/modiy/delete entries. I want to store those in an .INI file when the program closes and reload when it starts again. Anyone looking at the .INI file (for instance, opening it in Notepad) should not be able to read those strings.
我想我可以将组件作为二进制文件流式传输,但为了放心,我宁愿使用用户提供的密码对字符串进行加密.出于此应用程序的目的,.INI 文件部分名称或密钥值是否是人类可读的并不重要,我只想加密数据,当存储在磁盘上时给我一些列表:
I suppose that I could just stream the compnent as binary, but for eace of mind I would rather encrypt the strings using a user provided password. For the purpose of this applciation it does not matter if .INI file section names or keyte values are human readable, I just want to encrypt the data, giving me something list this when stored on disk:
[config]
numEntries=3
[listbox]
0=ywevdyuvewfcyuw
1=edw
2=hr4uifareiuf
推荐答案
这是 Tinifile 的替代品.
ReadString 和 WriteString 被覆盖,这些在内部用于 Read/WriteFloat、Read/WriteInteger 等.
This is a replacement for Tinifile.
ReadString and WriteString are overridden, these are internal used to for Read/WriteFloat, Read/WriteInteger etc.
字符串被加密并存储为十六进制字符串.
Strings are encrypted and stored as HEX-Strings.
演示用法:
uses CryptingIni;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
ini:TCryptingIni;
begin
ini:=TCryptingIni.Create('C: emp est.ini');
ini.UseInternalVersion(1234);
ini.WriteFloat('Sect','Float',123.456);
ini.WriteString('Sect2','String','How to encode');
ini.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
ini:TCryptingIni;
begin
ini:=TCryptingIni.Create('C: emp est.ini');
ini.UseInternalVersion(1234);
Showmessage(FloatToStr(ini.ReadFloat('Sect','Float',0)));
Showmessage(ini.ReadString('Sect2','String',''));
Showmessage(ini.ReadString('SectUnkknow','Showdefault','DEFAULT'));
ini.Free;
end;
您可以通过UseInternalVersion使用内部加密方法,或提供自己的程序
过程 SetCryptingData(aEncryptProc, aDecryptProc: CryptingProc; aKey: Word);
You may use internal encryption method by UseInternalVersion, or provide own procedures with
Procedure SetCryptingData(aEncryptProc, aDecryptProc: CryptingProc; aKey: Word);
unit CryptingIni;
// 2013 by Thomas Wassermann
interface
uses
Windows, SysUtils, Variants, Classes, inifiles;
type
CryptingProc = Function(const InString: String; Key: Word): String;
TCryptingIni = Class(TInifile)
function ReadString(const Section, Ident, Default: string): string; override;
procedure WriteString(const Section, Ident, Value: String); override;
private
FEncryptProc: CryptingProc;
FDecryptProc: CryptingProc;
FKey: Word;
public
Procedure SetCryptingData(aEncryptProc, aDecryptProc: CryptingProc; aKey: Word);
Procedure UseInternalVersion(aKey: Word);
End;
implementation
const
c1 = 52845;
c2 = 22719;
Type
TByteArray = Array [0 .. 0] of byte;
Function AsHexString(p: Pointer; cnt: Integer): String;
var
i: Integer;
begin
Result := '';
for i := 0 to cnt do
Result := Result + '$' + IntToHex(TByteArray(p^)[i], 2);
end;
Procedure MoveHexString2Dest(Dest: Pointer; Const HS: String);
var
i: Integer;
begin
i := 1;
while i < Length(HS) do
begin
TByteArray(Dest^)[i div 3] := StrToInt(Copy(HS, i, 3));
i := i + 3;
end;
end;
function EncryptV1(const s: string; Key: Word): string;
var
i: smallint;
ResultStr: string;
UCS: WIDEString;
begin
Result := s;
if Length(s) > 0 then
begin
for i := 1 to (Length(s)) do
begin
Result[i] := Char(byte(s[i]) xor (Key shr 8));
Key := (smallint(Result[i]) + Key) * c1 + c2
end;
UCS := Result;
Result := AsHexString(@UCS[1], Length(UCS) * 2 - 1)
end;
end;
function DecryptV1(const s: string; Key: Word): string;
var
i: smallint;
sb: String;
UCS: WIDEString;
begin
if Length(s) > 0 then
begin
SetLength(UCS, Length(s) div 3 div 2);
MoveHexString2Dest(@UCS[1], s);
sb := UCS;
SetLength(Result, Length(sb));
for i := 1 to (Length(sb)) do
begin
Result[i] := Char(byte(sb[i]) xor (Key shr 8));
Key := (smallint(sb[i]) + Key) * c1 + c2
end;
end
else
Result := s;
end;
{ TCryptingIni }
function TCryptingIni.ReadString(const Section, Ident, Default: string): string;
begin
if Assigned(FEncryptProc) then
Result := inherited ReadString(Section, Ident, FEncryptProc(Default, FKey))
else
Result := inherited ReadString(Section, Ident, Default);
if Assigned(FDecryptProc) then
Result := FDecryptProc(Result, FKey);
end;
procedure TCryptingIni.SetCryptingData(aEncryptProc, aDecryptProc: CryptingProc; aKey: Word);
begin
FEncryptProc := aEncryptProc;
FDecryptProc := aDecryptProc;
FKey := aKey;
end;
procedure TCryptingIni.UseInternalVersion(aKey: Word);
begin
FKey := aKey;
FEncryptProc := EncryptV1;
FDecryptProc := DecryptV1;
end;
procedure TCryptingIni.WriteString(const Section, Ident, Value: String);
var
s: String;
begin
if Assigned(FEncryptProc) then
s := FEncryptProc(Value, FKey)
else
s := Value;
inherited WriteString(Section, Ident, s);
end;
end.
这篇关于使用密码加密 .INI 文件字符串的简单代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!