We have a Delphi 2007 routine used to encrypt passwords in a table. The routine was originally grabbed from a CompuServe post a decade or more ago, and a significant amount of data encrypted with this routine exists.
The heart of the original routine is this:
chr(ord(Str[I]) xor not(ord(Id[I mod length(Id) + 1])));
I knew the conversion to Delphi XE would be problematic because of Unicode, so I broke that code out into a function that displays each step of the calculations in a memo:
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;
Like ROT13, the same routine is used to both encrypt and decrypt. If I feed it a string like 'ABCDEFGHI', the Delphi 2007 version can take the resulting encrypted string, run it through the same routine, and get back the original string. The version in Delphi XE, however, doesn't quite work. I've made some tweaks (included above) to improve it, but on the OstrI step it falls apart. I think it has something to do with performing an Ord on a (Wide) Char, but that's the closest I can get.
Any advice greatly appreciated.
Edited
Here is the original Delphi 2007 code:
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;
We actually have to convert this not only to Delphi XE for new versions of our existing software, but also to C# for a new web-based front end.
Simple approach is, in essence, as follows:
string
to AnsiString
.Char
to AnsiChar
.Chr()
to AnsiChar()
.There may be more nuances to your code. Ideally I'd like to see the original Delphi 2007 version of the code.
Having posted the original code, I think you should can use this routine in 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;
Note that I changed the code to take input as a const
string and to use Result
as the working buffer. This is not necessary for your ANSI/Unicode needs, but feels more natural to me!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With