Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将这个XOR加密函数从Delphi转换为C#?_C#_Delphi_Encryption - Fatal编程技术网

如何将这个XOR加密函数从Delphi转换为C#?

如何将这个XOR加密函数从Delphi转换为C#?,c#,delphi,encryption,C#,Delphi,Encryption,下面的Delphi例程源于很久以前的CompuServe发布,用于加密数据库中的各种信息。下面是Delphi2007和Delphi XE版本(多亏了Unicode差异方面的一些帮助) 我们一直在尝试将其转换为C#,并且已经接近尾声,但我们在某些地方遗漏了一些东西。不幸的是,我们的德尔福人(我)不认识C#,而C#人对德尔福来说是新手。C#没有(似乎)AnsiString的概念,所以解决方案可能涉及字节或字符数组 如果您能帮助我们将其转换为C#,我们将不胜感激 Delphi 2007版本(ASCII

下面的Delphi例程源于很久以前的CompuServe发布,用于加密数据库中的各种信息。下面是Delphi2007和Delphi XE版本(多亏了Unicode差异方面的一些帮助)

我们一直在尝试将其转换为C#,并且已经接近尾声,但我们在某些地方遗漏了一些东西。不幸的是,我们的德尔福人(我)不认识C#,而C#人对德尔福来说是新手。C#没有(似乎)AnsiString的概念,所以解决方案可能涉及字节或字符数组

如果您能帮助我们将其转换为C#,我们将不胜感激

Delphi 2007版本(ASCII)

Delphi XE版本(Unicode)

我也不懂C#,所以这可能是非常不习惯的

static string EncodeDecode(string str)
{
    byte[] hash = new byte[63] { 94, 37, 49, 50, 104, 68, 86, 106, 69, 68, 49, 126, 
        126, 35, 50, 57, 97, 102, 100, 109, 83, 68, 96, 54, 90, 118, 85, 89, 64, 
        104, 98, 107, 68, 66, 67, 51, 102, 110, 55, 89, 55, 101, 117, 70, 124, 82, 
        55, 57, 51, 52, 48, 57, 51, 42, 55, 97, 45, 124, 45, 32, 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);
}
@Groo提出了一个很好的观点,即可以更清晰地初始化散列:

byte[] hash = ANSI.GetBytes(@"^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|-  Q`");
C#中的
String
是以UTF-16编码的字符序列,如中所述。实际上,在您决定将其序列化为二进制(即,将其转换为字节数组)之前,您根本不应该担心这一点。在这种情况下,在
System.Text
命名空间中有一个名为的类,它支持将
字符串
编码为您想要的任何编码

Delphi中的
AnsiString
基本上是一个ASCII字符串(不,它实际上是一个ANSI字符串,如名称所示),其中每个字符保证正好有8位。这是一种相对“简单”的编码方式,因为它具有固定的大小,被广泛接受并与传统系统兼容(但不允许编码超过255个字符)

换句话说,您的两个版本都处理相同类型的编码,但是unicode版本现在明确地将遗留字符串定义为
AnsiString
s。这意味着后一个版本实际上不支持Unicode字符串,但需要使用新的Delphi版本更改类型


@David在我写这篇冗长的废话时所做的基本上就是我要写的,唯一的例外是我会使用编码来代替([edit],并且会因为ASCII只使用较低的7位来编码字符而失败,正如David在下面提到的那样)。是最常被称为“ANSI”的编码(尽管,如果你查看那篇Wiki文章,你会发现,根据Microsoft的说法,用于表示Windows代码页的术语ANSI是一个历史参考,但现在在Windows社区仍然是一个用词不当的词)。

我相信
~hash[(i+1%…
应该是
~hash[i%…
,因为C#string索引是基于0的。@John,你认为错了。需要(i+1)来匹配Delphi版本。解决它。在Delphi中,我们有
i mod Length(hash)+1
对于第一次循环的
I=1
,它给出了第二个字符的值2。因此,我们需要在C中使用
(I+1)%length
,当
I=0
第一次循环时,得到第二个字符(索引1)。可能不是惯用的。(我知道).但是我把字符串版本插入了我在VS中处理的乱七八糟的代码中,瞧,它似乎起了作用。现在编写百万随机短语测试代码。非常感谢!@Eric,@David:我的2c应该是在方法之外的某个地方编写类似于
byte[]hash=yourEncoding.GetBytes(yourHashString);
(你不想在每次通话中重复,但我甚至不想问David是如何从最初的帖子中获得这些数字的:-D)。@Groo我在Delphi中使用了for循环来获得这些数字,但我同意yourEncoding.GetBytes()更好。Encoding.ASCII不起作用。它只有7位宽。你需要一个8位编码。合理的猜测是它是1252。@大卫:你是对的。ASCII是一个7位字符集。Delphi的ansisting是一个8位字符集,我搞错了。实际上有很多8位ANSI编码,1252是最广泛使用的英语。请注意,我不同意通过这句话,1252的卓越之处在于!@David::)最后要检查文档中的正确编码并使用它。这些数据可能很容易只使用最低的7位(例如,哈希字符串).我只是想解释一下编码在C#中基本上是如何工作的。整个过程是臭名昭著的。只需注意:现在您的加密方法包括密钥(这是您的“哈希”字符串)是完全公开的,您应该尽快更改此字符串,否则您的数据在抵御攻击者时根本不安全。但是,您可以完全切换到更好的算法。感谢Paŭlo-我在发布之前弄坏了密钥。我们的实际密钥大不相同。
static string EncodeDecode(string str)
{
    byte[] hash = new byte[63] { 94, 37, 49, 50, 104, 68, 86, 106, 69, 68, 49, 126, 
        126, 35, 50, 57, 97, 102, 100, 109, 83, 68, 96, 54, 90, 118, 85, 89, 64, 
        104, 98, 107, 68, 66, 67, 51, 102, 110, 55, 89, 55, 101, 117, 70, 124, 82, 
        55, 57, 51, 52, 48, 57, 51, 42, 55, 97, 45, 124, 45, 32, 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);
}
static byte[] EncodeDecode(byte[] input)
{
    byte[] hash = new byte[63] { 94, 37, 49, 50, 104, 68, 86, 106, 69, 68, 49, 126, 
        126, 35, 50, 57, 97, 102, 100, 109, 83, 68, 96, 54, 90, 118, 85, 89, 64, 
        104, 98, 107, 68, 66, 67, 51, 102, 110, 55, 89, 55, 101, 117, 70, 124, 82, 
        55, 57, 51, 52, 48, 57, 51, 42, 55, 97, 45, 124, 45, 32, 32, 81, 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;
}
byte[] hash = ANSI.GetBytes(@"^%12hDVjED1~~#29afdmSD`6ZvUY@hbkDBC3fn7Y7euF|R7934093*7a-|-  Q`");