使用密码加密 .INI 文件字符串的简单代码 [英] Simple code to encrypt an .INI file string using a password

查看:47
本文介绍了使用密码加密 .INI 文件字符串的简单代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找比 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆