以下Delphi例程最初来自很久以前的CompuServe发布,用于加密我们数据库中的各种信息.下面是Delphi 2007和(由于一些有关Unicode差异的SO帮助)Delphi XE版本.
我们一直在尝试将其转换为C#,并且已经接近了,但我们在某处遗漏了某些东西.不幸的是,我们的Delphi家伙(我)不知道C#,而C#家伙是Delphi的新手. C#没有(似乎)具有AnsiString的概念,因此解决方案可能涉及字节或字符数组?
我们非常感谢将此转换为C#的任何帮助.
Delphi 2007版(ASCII)
function EncodeDecode(Str: string): string; const Hash: string = '^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|- Q`'; var I: Integer; begin for I := 1 to Length (Str) do Str[I] := chr (ord (Str[I]) xor not (ord (Hash[I mod Length (Hash) + 1]))); Result := Str; end;
Delphi XE版本(Unicode)
function TfrmMain.EncodeDecode(Str: AnsiString): AnsiString; const Hash: string = '^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|- Q`'; var I: Integer; begin Result := Str; for I := 1 to Length (Result) do Result[I] := AnsiChar (ord (Result[I]) xor not (Ord (Hash[I mod Length (Hash) + 1]))); end;
解决方法
我也不知道C#,所以这可能是严重的非惯用语.
static string EncodeDecode(string str) { byte[] hash = new byte[63] { 94,37,49,50,104,68,86,106,69,126,35,57,97,102,100,109,83,96,54,90,118,85,89,64,98,107,66,67,51,110,55,101,117,70,124,82,52,48,42,45,32,81,96 }; Encoding ANSI = Encoding.GetEncoding(1252); byte[] input = ANSI.GetBytes(str); byte[] output = new byte[input.Length]; for (int i = 0; i < input.Length; i++) output[i] = (byte)(input[i] ^ ~hash[(i + 1) % hash.Length]); return ANSI.GetString(output); }
我假设您的ANSI字符串是使用Windows 1252编码的,但是您恰好使用不同的代码页对旧数据进行了编码,显而易见的是如何更改它.
由于C#没有相当于Delphi的8位字符串类型,我个人非常想使用byte []而不是字符串.
这样做就像这样:
static byte[] EncodeDecode(byte[] input) { byte[] hash = new byte[63] { 94,96 }; byte[] output = new byte[input.Length]; for (int i = 0; i < input.Length; i++) output[i] = (byte)(input[i] ^ ~hash[(i + 1) % hash.Length]); return output; }
@Groo提出了一个很好的观点,即哈希可以更干净地初始化列出这个:
byte[] hash = ANSI.GetBytes(@"^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|- Q`");