[英]C# Converting a XOR crypt function
我一直在努力将C ++加密方法转换为C#。 问题是,我无法以我想要的方式加密/解密。
这个想法很简单,我捕获一个数据包,并解密它。 输出将是:数据包大小 - 命令/操作 - 空(结束)
(解密器切断了第一个和最后两个字节)
C ++代码是这样的:
// Crypt the packet with Xor operator
void cryptPacket(char *packet)
{
unsigned short paksize=(*((unsigned short*)&packet[0])) - 2;
for(int i=2; i<paksize; i++)
{
packet[i] = 0x61 ^ packet[i];
}
}
所以我认为如果我不想使用指针,这将适用于C#:
public static char[] CryptPacket(char[] packet)
{
ushort paksize = (ushort) (packet.Length - 2);
for(int i=2; i<paksize; i++)
{
packet[i] = (char) (0x61 ^ packet[i]);
}
return packet;
}
- 但事实并非如此,返回的值只是另一行rubish而不是解密值。 给出的输出是:..O♦&/ OOOe。
嗯..至少'/'出于某种原因在正确的位置。
更多信息:
十六进制值:0C 00 E2 66 65 47 4E 09 04 13 65 00
纯文字:... feGN ... e。
解密:XX / hereXX
X =未知值,我真的不记得了,但没关系。
这就是我现在可以提供的所有信息,因为我正在写这篇文章。
感谢您的时间。
如果你没有看到这个问题:
如果有人能够查看代码以查看代码有什么问题,或者是否有另一种方法可以做到这一点,那就太棒了。 我正在转换这段代码,因为我对C ++很恐怖,并希望用该代码创建一个C#应用程序。
Ps:代码标签等都很痛苦,所以如果间距等有些混乱,我很抱歉。
您的问题可能是因为.NET的char是unicode,一些字符将使用多个字节,并且您的位掩码只有一个字节长。 因此,最重要的字节将保持不变。
我刚尝试了你的功能,似乎没问题:
class Program
{
// OP's method: http://stackoverflow.com/questions/4815959
public static byte[] CryptPacket(byte[] packet)
{
int paksize = packet.Length - 2;
for (int i = 2; i < paksize; i++)
{
packet[i] = (byte)(0x61 ^ packet[i]);
}
return packet;
}
// http://stackoverflow.com/questions/321370 :)
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length).
Where(x => 0 == x % 2).
Select(x => Convert.ToByte(hex.Substring(x, 2), 16)).
ToArray();
}
static void Main(string[] args)
{
string hex = "0C 00 E2 66 65 47 4E 09 04 13 65 00".Replace(" ", "");
byte[] input = StringToByteArray(hex);
Console.WriteLine("Input: " + ASCIIEncoding.ASCII.GetString(input));
byte[] output = CryptPacket(input);
Console.WriteLine("Output: " + ASCIIEncoding.ASCII.GetString(output));
Console.ReadLine();
}
}
控制台输出:
Input: ...feGN.....
Output: ...../here..
(where '.' represents funny ascii characters)
你的CryptPacket
方法用输出值覆盖初始数组似乎有点臭。 并且不会修剪那些不相关的字符。 但是如果你试图移植一些东西,我猜你应该知道你在做什么。
您还可以考虑修剪输入数组,首先删除不需要的字符,然后使用通用的ROT13方法( 如此方法)。 这样你就拥有了自己的“专用”版本,在crypt函数本身内部有2字节偏移,而不是像:
public static byte[] CryptPacket(byte[] packet)
{
// create a new instance
byte[] output = new byte[packet.Length];
// process ALL array items
for (int i = 0; i < packet.Length; i++)
{
output[i] = (byte)(0x61 ^ packet[i]);
}
return output;
}
这是从C ++到C#的几乎字面翻译,它似乎有效:
var packet = new byte[] {
0x0C, 0x00, 0xE2, 0x66, 0x65, 0x47,
0x4E, 0x09, 0x04, 0x13, 0x65, 0x00
};
CryptPacket(packet);
// displays "....../here." where "." represents an unprintable character
Console.WriteLine(Encoding.ASCII.GetString(packet));
// ...
void CryptPacket(byte[] packet)
{
int paksize = (packet[0] | (packet[1] << 8)) - 2;
for (int i = 2; i < paksize; i++)
{
packet[i] ^= 0x61;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.