将C中包含无符号字符指针的代码移植到C#
我有C语言的代码,需要移植到C#: 应该是这样的:将C中包含无符号字符指针的代码移植到C#,c#,c,encryption,C#,C,Encryption,我有C语言的代码,需要移植到C#: 应该是这样的: A5 6F 93 8B... 它还说第一个字节没有加密,所以A5保持不变 编辑以澄清:规范只是说您应该跳过第一个字节,它没有详细说明,因此我猜您只是将序列从位置1传递到跳过第一个字节的最后一个位置 但我对这个C#port的结果是: 这个端口是正确的还是我遗漏了什么 编辑2:为了进一步澄清,这是一个封闭的协议,所以我无法详细说明,这就是为什么我提供了足够的信息来帮助我移植代码,C代码是提供给我的代码,这就是规范所说的。 真正的问题是规范中的“0
A5 6F 93 8B...
它还说第一个字节没有加密,所以A5保持不变
编辑以澄清:规范只是说您应该跳过第一个字节,它没有详细说明,因此我猜您只是将序列从位置1传递到跳过第一个字节的最后一个位置
但我对这个C#port的结果是:
这个端口是正确的还是我遗漏了什么
编辑2:为了进一步澄清,这是一个封闭的协议,所以我无法详细说明,这就是为什么我提供了足够的信息来帮助我移植代码,C代码是提供给我的代码,这就是规范所说的。
真正的问题是规范中的“0xAA”是错误的,这就是为什么输出不是预期的输出。这里提供的C#代码和接受的答案都是正确的。端口看起来不错
在这种情况下,我要做的是拿出一张纸和一支笔,写出二进制字节,进行异或运算,然后进行加法运算。现在将其与C和C代码进行比较。在C中,您溢出了字节,因此它被截断为0x72。以下是在二进制和十六进制中转换0x03的数学:
00000011 0x003
^ 10101010 0x0AA
= 10101001 0x0A9
+ 11001001 0x0C9
= 101110010 0x172
移植看起来是正确的;你能解释为什么03应该变成6F吗?到03时,结果似乎偏离了“预期”值这一事实对我来说有点可疑。您提供的示例与C示例中的代码不一致,C和C代码产生相同的结果。与C中的原始方法相同,我们首先假设序列通过调用
加密缓冲区
- 最初在
a5 03 18 01…
a5 03 18 01 ... => d8 72 7b 74 ...
然后在d8 72 7b 74…
d8 72 7b 74 ... => 3b a1 9a a7 ...
d8 8e 02 ea ... => 3b ed 71 09 ...
- 最初在
A56F 93 8b上调用…
a5 6f 93 8b ... => d8 8e 02 ea ...
然后在d8 8e 02 ea上…
d8 72 7b 74 ... => 3b a1 9a a7 ...
d8 8e 02 ea ... => 3b ed 71 09 ...
我们知道这是不可行的
当然,您可能有一个非对称的解密方法;但首先,我们需要a5031801…=>a5 6f 93 8b…
或任何可能的幻数证明方向相反。使用蛮力方法进行分析的代码放在柱子的后面
我把这个神奇的数字作为测试变量。通过再现性分析,我们发现在连续变化的幻数上,每调用256次就可以再现原始序列。好吧,根据我们所经历的,这仍然是可能的
然而,可行性分析从original=>expected
和expected=>original
两个方向测试了所有256*256=65536
案例,没有一个成功
现在我们知道没有办法将加密序列解密到预期的结果
因此,我们只能判断两种语言或您的代码的预期行为是相同的,但是对于,由于假设被打破,预期结果是不可能的
分析代码
public void CryptoBuffer(byte[] buffer, ushort magicShort) {
var magicBytes=BitConverter.GetBytes(magicShort);
var count=buffer.Length;
for(var i=0; i<count; i++) {
buffer[i]^=magicBytes[1];
buffer[i]+=magicBytes[0];
}
}
int Analyze(
Action<byte[], ushort> subject,
byte[] expected, byte[] original,
ushort? magicShort=default(ushort?)
) {
Func<byte[], String> LaHeX= // narrowing bytes to hex statement
arg => arg.Select(x => String.Format("{0:x2}\x20", x)).Aggregate(String.Concat);
var temporal=(byte[])original.Clone();
var found=0;
for(var i=ushort.MaxValue; i>=0; --i) {
if(found>255) {
Console.WriteLine(": might found more than the number of square root; ");
Console.WriteLine(": analyze stopped ");
Console.WriteLine();
break;
}
subject(temporal, magicShort??i);
if(expected.SequenceEqual(temporal)) {
++found;
Console.WriteLine("i={0:x2}; temporal={1}", i, LaHeX(temporal));
}
if(expected!=original)
temporal=(byte[])original.Clone();
}
return found;
}
void PerformTest() {
var original=new byte[] { 0xa5, 0x03, 0x18, 0x01 };
var expected=new byte[] { 0xa5, 0x6f, 0x93, 0x8b };
Console.WriteLine("--- reproducibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, original, original, 0xaac9));
Console.WriteLine();
Console.WriteLine("--- feasibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, expected, original));
Console.WriteLine();
// swap original and expected
var temporal=original;
original=expected;
expected=temporal;
Console.WriteLine("--- reproducibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, original, original, 0xaac9));
Console.WriteLine();
Console.WriteLine("--- feasibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, expected, original));
Console.WriteLine();
}
public void CryptoBuffer(字节[]缓冲区,ushort magicShort){
var magicBytes=位转换器.GetBytes(magicShort);
var count=buffer.Length;
对于(vari=0;i arg.Select(x=>String.Format(“{0:x2}\x20”,x)).Aggregate(String.Concat);
var temporal=(字节[])original.Clone();
var=0;
对于(var i=ushort.MaxValue;i>=0;--i){
如果(发现>255){
WriteLine(“:可能发现大于平方根数;”);
Console.WriteLine(“:analyze stopped”);
Console.WriteLine();
打破
}
受试者(暂时性,magicShort??i);
if(预期的。SequenceEqual(暂时)){
++发现;
WriteLine(“i={0:x2};temporal={1}”,i,LaHeX(temporal));
}
如果(预期!=原件)
时态=(字节[])original.Clone();
}
发现退货;
}
无效性能测试(){
var original=新字节[]{0xa5,0x03,0x18,0x01};
var预期=新字节[]{0xa5,0x6f,0x93,0x8b};
Console.WriteLine(“---再现性分析---”);
WriteLine(“找到:{0}”,Analyze(CryptoBuffer,original,original,0xaac9));
Console.WriteLine();
Console.WriteLine(“---可行性分析---”);
WriteLine(“找到:{0}”,Analyze(CryptoBuffer,应为,原始));
Console.WriteLine();
//交换原始和预期
var时间=原始;
原始=预期;
预期=暂时的;
Console.WriteLine(“---再现性分析---”);
WriteLine(“找到:{0}”,Analyze(CryptoBuffer,original,original,0xaac9));
Console.WriteLine();
Console.WriteLine(“---可行性分析---”);
WriteLine(“找到:{0}”,Analyze(CryptoBuffer,应为,原始));
Console.WriteLine();
}
让我们把它分解一下,好吗,一步一个脚印
void CryptoBuffer(unsigned char *Buffer, unsigned short length)
{
unsigned short i;
for(i=0; i < length; i++)
{
*Buffer ^= 0xAA;
*Buffer++ += 0xC9;
}
}
void CryptoBuffer(无符号字符*缓冲区,无符号短长度)
{
无符号短i;
对于(i=0;i
抛开其他一些评论不谈,这是在C/C++中通常做这些事情的方式。这段代码没有什么特别之处,也不太复杂,但我认为最好将其分解,向您展示会发生什么
注意事项:
无符号字符基本上与c中的字节相同#
无符号长度的值在0-65536之间。Int应该起作用
缓冲区有一个post增量
字节分配(+=0xC9)将溢出。如果溢出,则在这种情况下将截断为8位
缓冲区由ptr传递,因此调用方法中的指针将
public void CryptoBuffer(byte[] buffer, ushort magicShort) {
var magicBytes=BitConverter.GetBytes(magicShort);
var count=buffer.Length;
for(var i=0; i<count; i++) {
buffer[i]^=magicBytes[1];
buffer[i]+=magicBytes[0];
}
}
int Analyze(
Action<byte[], ushort> subject,
byte[] expected, byte[] original,
ushort? magicShort=default(ushort?)
) {
Func<byte[], String> LaHeX= // narrowing bytes to hex statement
arg => arg.Select(x => String.Format("{0:x2}\x20", x)).Aggregate(String.Concat);
var temporal=(byte[])original.Clone();
var found=0;
for(var i=ushort.MaxValue; i>=0; --i) {
if(found>255) {
Console.WriteLine(": might found more than the number of square root; ");
Console.WriteLine(": analyze stopped ");
Console.WriteLine();
break;
}
subject(temporal, magicShort??i);
if(expected.SequenceEqual(temporal)) {
++found;
Console.WriteLine("i={0:x2}; temporal={1}", i, LaHeX(temporal));
}
if(expected!=original)
temporal=(byte[])original.Clone();
}
return found;
}
void PerformTest() {
var original=new byte[] { 0xa5, 0x03, 0x18, 0x01 };
var expected=new byte[] { 0xa5, 0x6f, 0x93, 0x8b };
Console.WriteLine("--- reproducibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, original, original, 0xaac9));
Console.WriteLine();
Console.WriteLine("--- feasibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, expected, original));
Console.WriteLine();
// swap original and expected
var temporal=original;
original=expected;
expected=temporal;
Console.WriteLine("--- reproducibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, original, original, 0xaac9));
Console.WriteLine();
Console.WriteLine("--- feasibility analysis --- ");
Console.WriteLine("found: {0}", Analyze(CryptoBuffer, expected, original));
Console.WriteLine();
}
void CryptoBuffer(unsigned char *Buffer, unsigned short length)
{
unsigned short i;
for(i=0; i < length; i++)
{
*Buffer ^= 0xAA;
*Buffer++ += 0xC9;
}
}
void CryptoBuffer(unsigned char *Buffer, unsigned short length)
{
unsigned short i;
for(i=0; i < length; i++)
{
*Buffer ^= 0xAA;
unsigned char *tmp = Buffer;
*tmp += 0xC9;
Buffer = tmp + 1;
}
}
void CryptoBuffer(unsigned char *Buffer, unsigned short length)
{
unsigned short i;
for(i=0; i < length; i++)
{
*Buffer ^= 0xAA;
*Buffer += 0xC9;
++Buffer;
}
}
private void CryptoBuffer(byte[] Buffer, int length)
{
for (int i=0; i<length; ++i)
{
Buffer[i] = (byte)((Buffer[i] ^ 0xAA) + 0xC9);
}
}
static void Main(string[] args)
{
byte[] orig = new byte[] { 0x03, 0x18, 0x01 };
byte[] target = new byte[] { 0x6F, 0x93, 0x8b };
for (int i = 0; i < 256; ++i)
{
for (int j = 0; j < 256; ++j)
{
bool okay = true;
for (int k = 0; okay && k < 3; ++k)
{
byte tmp = (byte)((orig[k] ^ i) + j);
if (tmp != target[k]) { okay = false; break; }
}
if (okay)
{
Console.WriteLine("Solution for i={0} and j={1}", i, j);
}
}
}
Console.ReadLine();
}