Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.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
将C中包含无符号字符指针的代码移植到C#_C#_C_Encryption - Fatal编程技术网

将C中包含无符号字符指针的代码移植到C#

将C中包含无符号字符指针的代码移植到C#,c#,c,encryption,C#,C,Encryption,我有C语言的代码,需要移植到C#: 应该是这样的: A5 6F 93 8B... 它还说第一个字节没有加密,所以A5保持不变 编辑以澄清:规范只是说您应该跳过第一个字节,它没有详细说明,因此我猜您只是将序列从位置1传递到跳过第一个字节的最后一个位置 但我对这个C#port的结果是: 这个端口是正确的还是我遗漏了什么 编辑2:为了进一步澄清,这是一个封闭的协议,所以我无法详细说明,这就是为什么我提供了足够的信息来帮助我移植代码,C代码是提供给我的代码,这就是规范所说的。 真正的问题是规范中的“0

我有C语言的代码,需要移植到C#:

应该是这样的:

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();
    }