我们有一个Delphi 2007例程用于加密表中的密码。该例程最初是在十年或更久以前从CompuServe帖子中获取的,并且存在大量使用此例程加密的数据。
原始程序的核心是:
chr(ord(Str[I]) xor not(ord(Id[I mod length(Id) + 1])));
我知道由于Unicode的原因,转换为Delphi XE会有问题,因此我将该代码分解为一个函数,该函数在备忘录中显示计算的每一步:
function TfrmMain.EncodeDecode(AString: string): string;
const
Hash: string = '^%12h2DBC3f41~~#6093fn7mY7eujEhbFD3DZ|R9aSDVvUY@dk79*7a-|- Q';
var
I: Integer;
IMod: Integer;
HMod: Char;
OMod: Integer;
AStrI: Char;
OStrI: Integer;
ResultStr: string;
XOrNot: Integer;
ChrXN: AnsiChar;
begin
Memo1.Clear;
Memo1.Lines.Add ('AStrI' + TAB + 'IMod' + TAB + 'HMod' +
TAB + 'OMod' + TAB + 'OStrI' + TAB + 'XOrNot' + TAB + 'ChrXN');
for I := 1 to Length (AString) do
begin
IMod := I mod Length (Hash) + 1;
HMod := Hash [IMod];
OMod := Ord (HMod);
AStrI := AString[I];
OStrI := Ord (AStrI); // This is where things go south
XOrNot := OStrI xor not OMod;
ChrXN := AnsiChar (XOrNot);
ResultStr := ResultStr + ChrXN;
Memo1.Lines.Add (AStrI + TAB +
IntToStr (IMod) + TAB +
HMod + TAB +
IntToStr (OMod) + TAB +
IntToStr (OStrI) + TAB +
IntToStr (XOrNot) + TAB +
ChrXN);
end;
Memo1.Lines.Add (ResultStr);
Result := ResultStr;
end;
与ROT13一样,相同的例程用于加密和解密。如果我给它添加一个像'ABCDEFGHI'这样的字符串,Delphi 2007版本可以获取生成的加密字符串,通过相同的例程运行它,并返回原始字符串。但是,Delphi XE中的版本不能完全工作。我做了一些调整(包括在上面)以改进它,但是在OstrI步骤中它崩溃了。我认为这与在(宽)字符上执行Ord有关,但这是我能得到的最接近的。
任何建议都非常感谢。
被修改
以下是原始的Delphi 2007代码:
function EncodeDecode(Str: string): string;
const
Id: string = '^%12h2DBC3f41~~#6093fn7mY7eujEhbFD3DZ|R9aSDVvUY@dk79*7a-|- Q';
var
I: Integer;
begin
for I := 1 to Length (Str) do
Str[I] := chr (ord (Str[I]) xor not (ord (Id[I mod Length (Id) + 1])));
Result := Str;
end;
我们实际上不仅要将这个转换为Delphi XE用于我们现有软件的新版本,还要转换为C#用于新的基于Web的前端。
答案 0 :(得分:8)
简单的方法实质上如下:
string
更改为AnsiString
。Char
更改为AnsiChar
。Chr()
更改为AnsiChar()
。您的代码可能会有更多细微差别。理想情况下,我希望看到原始的Delphi 2007版本的代码。
发布原始代码后,我认为您应该可以在XE中使用此例程:
function EncodeDecode(const Str: AnsiString): AnsiString;
const
Id: AnsiString = '^%12h2DBC3f41~~#6093fn7mY7eujEhbFD3DZ|R9aSDVvUY@dk79*7a-|- Q';
var
I: Integer;
begin
Result := Str;
for I := 1 to Length(Result) do
Result[I] := AnsiChar(ord(Result[I]) xor not (ord(Id[I mod Length (Id) + 1])));
end;
请注意,我更改了代码以将输入作为const
字符串并使用Result
作为工作缓冲区。这对于您的ANSI / Unicode需求不是必需的,但对我来说感觉更自然!