问题
I'm following an article, http://www.4guysfromrolla.com/articles/091802-1.3.aspx, which shows how to convert Mike Shaffer's VB RC4 encryption to C#, however I'm getting different results than the original article, http://www.4guysfromrolla.com/webtech/010100-1.shtml.
Using this test link from the original article, http://www.4guysfromrolla.com/demos/rc4test.htm, with a password of "abc" and plain text of "testing123", I get "B9 F8 AA 5D 31 B1 8A 42 1E D4". However, when using the C# version, I get something slightly different: "b9 f8 aa 5d 31 b1 160 42 1e d4". I'm getting "160" instead of "8A".
Here's my method which converts the ASCII (final result of C# method) to hex:
public static string ConvertAsciiToHex(string input)
{
return string.Join(string.Empty, input.Select(c => Convert.ToInt32(c).ToString("X")).ToArray());
}
And here's the C# code I have from the article (modified to static class):
protected static int[] sbox = new int[256];
protected static int[] key = new int[256];
private static string password = "abc";
private static void RC4Initialize(string strPwd)
{
int intLength = strPwd.Length;
for (int a = 0; a <= 255; a++)
{
char ctmp = (strPwd.Substring((a % intLength), 1).ToCharArray()[0]);
key[a] = Microsoft.VisualBasic.Strings.Asc(ctmp);
sbox[a] = a;
}
int x = 0;
for (int b = 0; b <= 255; b++)
{
x = (x + sbox[b] + key[b]) % 256;
int tempSwap = sbox[b];
sbox[b] = sbox[x];
sbox[x] = tempSwap;
}
}
private static string EnDeCrypt(string text)
{
int i = 0;
int j = 0;
string cipher = "";
RC4Initialize(password);
for (int a = 1; a <= text.Length; a++)
{
int itmp = 0;
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
itmp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = itmp;
int k = sbox[(sbox[i] + sbox[j]) % 256];
char ctmp = text.Substring(a - 1, 1).ToCharArray()
[0];
itmp = Microsoft.VisualBasic.Strings.Asc(ctmp);
int cipherby = itmp ^ k;
cipher += Microsoft.VisualBasic.Strings.Chr(cipherby);
}
return cipher;
}
I'm calling the method like so:
public static string Encrypt(string text)
{
return ConvertAsciiToHex(EnDeCrypt(text));
}
RC4Encrypt.Encrypt("testing123");
What am I doing wrong?
回答1:
It's a difference between calls to Chr and ChrW.
Chr
will only take values between 0 and 255 and will return a char whose value is out of that range (at least on my machine as shown below). You were seeing a 138.
128 != 8364 (?) 130 != 8218 (,) 131 != 402 (ƒ) 132 != 8222 (,) 133 != 8230 (.) 134 != 8224 (+) 135 != 8225 (╪) 136 != 710 (^) 137 != 8240 (%) 138 != 352 (S) 139 != 8249 () 156 != 339 (o) 158 != 382 (z) 159 != 376 (Y)
For a better explanation, a VB.Net dev may be required... ;-)
Given that, however, there's little need for using the Microsoft.VisualBasic
calls (hardly a translation when calling VB... ;-) ) because using char
will work just fine for what you're doing.
itmp = ctmp; //there's an implicit conversion for char to int
int cipherby = itmp ^ k;
Console.WriteLine("cipherby = {0}", cipherby);
cipher += (char)cipherby; //just cast cipherby to a char
来源:https://stackoverflow.com/questions/17558361/converting-mike-shaffers-rc4encryption-to-c-sharp