使用密码加密.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.
提前感谢
[更新] / [赏金]只是为了清楚(如果原来不是apologies),我不想要哈希。我有一个列表框,用户可以添加/修改/删除条目。当程序关闭时,我想将它们存储在.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被覆盖,这些内部用于读/写浮动,读/写优化等。
This is a replacement for Tinifile.
ReadString and WriteString are overridden, these are internal used to for Read/WriteFloat, Read/WriteInteger etc.
字符串被加密,存储为HEX-Strings。
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:\temp\test.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:\temp\test.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屋!