【发布时间】:2011-07-07 19:05:32
【问题描述】:
我们有一个 Delphi 2007 例程用于加密表中的密码。该例程最初是从十年或更长时间前的 CompuServe 帖子中获取的,并且存在大量使用此例程加密的数据。
原套路的核心是这样的:
chr(ord(Str[I]) xor not(ord(Id[I mod length(Id) + 1])));
我知道转换到 Delphi XE 会因为 Unicode 而出现问题,所以我将代码分解成一个函数,在备忘录中显示计算的每个步骤:
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 的前端。
【问题讨论】:
-
更简洁地说:函数是一个involution(= 它自己的逆)。
-
我没有详细研究过上面的代码,但是我看到你正在混合
string和AnsiString(以及char和AnsiChar),这通常不是很好处理原始的二进制数据。但也许您已经意识到这一点,并且只是在以正确的方式做事? -
与其发布不起作用的代码,不如只发布 D2007 代码,其中一位用户将能够向您展示如何将其移植到 XE。
-
原始帖子已编辑以包含起始 D2007 代码。谢谢@DavidHeffernan,祝你好运:-)
-
@Eric:你肯定知道如何让事情变得复杂! ;)