繁体   English   中英

C# 程序似乎正在修改标记为只读的参数

[英]C# program seems to be modifying a parameter marked as readonly

我有一个名为ARCMF的 function 应该返回相同的伪随机 output 对于每组相同的输入statekeys都使用只读引用传递的关键字in 但是,当我尝试运行此 function 两次时,第一个和第二个结果永远不会彼此相等(但每次我重新启动程序时都相等)。 经过大量调试后,似乎有问题的变量被修改了。 我尝试将它设置为只读,但它仍然以某种方式被修改。 这让我困惑了好几个小时......

我所有的代码都在这个 repo 上。

这是我在调试期间在手表 window 中拥有的有问题的变量(从现在开始,我将其称为 IV),然后我将其传递给名为 ARCMF 的 function ...

var arc = new ARC128(key, iv);
var mf0 = arc.ARCMF(iv, arc.Schedule(key, iv, 1));
arc.PrintArray(mf0, "Main Function Iteration 0 Results");
var mf1 = arc.ARCMF(iv, arc.Schedule(key, iv, 1));
arc.PrintArray(mf1, "Main Function Iteration 1 Results");
c.WriteLine(Enumerable.SequenceEqual(mf0, mf1) ? "MF Gen success." : "MF Gen fail.");

internal byte[] ARCMF(in byte[] state, in byte[][] keys)
        {
            var output = state;
            for (int i = 0; i < 9; i++)
            {
                ARCLT.Permutate(ref output, ARCLT.MBLTv1, i);
                ARCBMGR(ref output);
                ARCLT.Permutate(ref output, ARCLT.SBLTv1, i);
                output = OTPArray(output, keys[i]);
            }
            return output; 
        }

IV 的修改具体发生在ARCLT.Permutate(ref output, ARCLT.MBLTv1, i);

为了帮助展示这一点,这里有一些截图。

之前(我无法嵌入图像:()之后

function 本身看起来像这样:

internal static void Permutate(ref byte[] io, in byte[] table, int seed =  1)
        {
            seed = (seed == 0) ? 1 : seed;
            for (int i = 0; i <= io.Length - 1; i++)
                io[i] = (byte)((io[i] * seed % 256) ^ table[i]);
        }

对于那些好奇的人,以下是程序输出的内容:

Main Function Iteration 0 Results: 785B62AFE54AB7FA7A4EE63D67A311A8
Main Function Iteration 1 Results: F47B4EF85524B92B6F210F9EDCD5786
MF Gen fail.

我应该怎么办?

更新 1:将置换 function 更改为

internal static byte[] Permutate(byte[] io, in byte[] table, int seed =  1)
        {
            var o = io;
            seed = (seed == 0) ? 1 : seed;
            for (int i = 0; i <= io.Length - 1; i++)
                o[i] = (byte)((o[i] * seed % 256) ^ table[i]);
            return o;
        }

没什么区别。

因为您使用的是ref关键字。 它允许子方法修改 memory 中的参数值。 在您的情况下,当您每次设置值时,参数output (字节结构类型)被修改两次:

io[i] = (byte)((io[i] * seed % 256) ^ table[i]); .

您将它与 Ref 关键字混合在一起。 Ref 将修改这些值。

制作它的副本并使用该副本。

var output = new byte[state.Length];
state.CopyTo(output, 0);

or 

var output = state.ToArray();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2025 STACKOOM.COM