我正在尝试将此Delphi代码转换为C#
function TWebModule1.DecodeA(Auth: string): Word;
var
iAuth: Cardinal;
r: Cardinal;
begin
iAuth := StrToInt64(Auth);
r := (iAuth and $FFFF0000) shr 16;
Result := (iAuth and $FFFF) xor r xor $9752;
end;
这是我用C#编写的内容,但它没有给我预期的结果。
private Int64 DecodeA(Int64 auth)
{
try
{
var r = (auth & 0xFFFF0000) >> 16;
var result = (auth & 0xFFFF) ^ r ^ 0x9752;
_log.DebugFormat("Decoding of {0} returned {1}", auth, result);
return result;
}
catch (Exception ex)
{
_log.Fatal(ex);
throw new Exception(ex.Message);
}
}
示例:auth = 3216841950的结果应为41022
感谢您提供的任何信息。
答案 0 :(得分:2)
If you use the same datatypes in both languages then it works just out of the box:
Delphi version
function DecodeA(iAuth: Int64): Int64;
var
r: Int64;
begin
r := (iAuth and $FFFF0000) shr 16;
Result := (iAuth and $FFFF) xor r xor $9752;
end;
C# version
private Int64 DecodeA(Int64 iAuth)
{
Int64 r = (iAuth & 0xFFFF0000) >> 16;
return (iAuth & 0xFFFF) ^ r ^ 0x9752;
}
In both languages DecodeA(3216841950) equals 13361
答案 1 :(得分:1)
关键是要了解这一点,以了解为什么Delphi开发人员选择使用StrToInt64
,考虑到其余代码在32位整数上运行。原因是StrToInt
返回带符号的32位整数,因此2^31
到2^32 - 1
范围内的值会导致错误。原始Delphi代码的开发人员通过将输入视为64位整数来处理此问题,这是一种包含32位无符号类型的完整范围的数据类型。
现在,在您的C#代码中,您可以非常直接地进行翻译,但是您不需要使用64位类型,就像Delphi代码那样。 Delphi代码在32位无符号整数上运行,并返回一个16位无符号整数。
ushort DecodeA(uint iauth)
{
uint r = (iauth & 0xffff0000) >> 16;
return (ushort) (iauth & 0xffff) ^ r ^ 0x9752;
}
ushort DecodeA(string auth)
{
return DecodeA(uint.Parse(auth));
}
这里我提供了两个重载,一个用于解析字符串的字符串输入,另一个用于输入无符号的32位整数。前者称后者。
请注意,我已经跟随Delphi代码并返回了一个16位无符号整数ushort
。