【问题标题】:Please help figure out what this C# method is doing?请帮助弄清楚这个 C# 方法在做什么?
【发布时间】:2010-06-27 03:42:37
【问题描述】:

我对这种方法所完成的工作有点困惑。它似乎试图将字节分解成半字节,并将半字节与其他字节的半字节重新组合以形成新字节,然后返回一个新的字节序列。

但是,我不认为,您可以使用模数、减法和除法从一个字节中取出半字节,也不能通过简单的乘法和加法重新组合它们。

我想更好地理解这个方法是如何工作的,以及它在做什么,所以我可以在它周围找到一些 cmets,然后看看它是否可以使用更标准的蚕食字节方法转换成更有意义的方法,甚至尽可能利用 .Net 4.0。

private static byte[] Process(byte[] bytes)
{
    Queue<byte> newBytes = new Queue<byte>();

    int phase = 0;
    byte nibble1 = 0;
    byte nibble2 = 0;
    byte nibble3 = 0;

    int length = bytes.Length-1;

    for (int i = 0; i < length; i++)
    {
        switch (phase)
        {
            case 0:
                nibble1 = (byte)((bytes[i] - (bytes[i] % 4)) / 4);
                nibble2 = (byte)(byte[i] % 4);
                nibble3 = 0;
                break;
            case 1:
                nibble2 = (byte)((nibble2 * 4) + (bytes[i] - (bytes[i] % 16))/16);
                nibble3 = (byte)(bytes[i] % 16);
                if (i < 4)
                {
                    newBytes.Clear();
                    newBytes.Enqueue((byte)((16 * nibble1) + nibble2));
                }
                else
                    newBytes.Enqueue((byte)((16 * nibble1) + nibble2));
                break;
            case 2:
                nibble1 = nibble3;
                nibble2 = (byte)((bytes[i] - (bytes[i] % 4)) / 4);
                nibble3 = (byte)(bytes[i] % 4);
                newBytes.Enqueue((byte)((16 * nibble1) + nibble2));
                break;
            case 3:
                nibble1 = (byte)((nibble3 * 4) + (bytes[i] - (bytes[i] % 16))/16);
                nibble2 = (byte)(bytes[i] % 16);
                newBytes.Enqueue((byte)((16 * nibble1) + nibble2));
                break;
        }

        phase = (phase + 1) % 4;
    }

    return newBytes.ToArray();
}

【问题讨论】:

  • 请注意 - 除以 4 与 &gt;&gt; 2 相同,除以 16 与 &gt;&gt; 4 相同。乘以它们是同一种左移。
  • Gnome - i &lt; 4 在前 4 次传递(前四个字节)期间为真。因此,它似乎丢弃了前 4 个结果。
  • 打开一个单独维护的相位变量而不是仅仅打开 i 的 mod 是第一个迹象表明这段代码的其余部分可能正在以困难的方式做事。
  • @Oded 您的答案和@driis 一样正确,所以很难选择,所以我根据他的回答先选择了。我喜欢这两个答案,他们非常有帮助,谢谢你们。

标签: c# .net-4.0 byte


【解决方案1】:

乘以 2 与将位左移一位相同。 (所以乘以 4 就是移动 2 个位置,依此类推)。

除以 2 与将位右移一位相同。

模数运算符用于屏蔽部分值。模数 N,其中 N = 2^p,将为您提供原始值的 (p-1) 位中包含的值。所以

value % 4

一样
value & 7    // 7 the largest value you can make with 3 bits (4-1). 4 + 2 +1.

加法和减法可用于组合值。例如,如果您知道 n 和 z 是 4 位值,那么以下两个语句都会将它们组合成一个字节,其中 n 位于高 4 位:

value = (n * 16) + z;

对比

value = (n << 4) | z;

【讨论】:

  • % 4 和 % 16 会有按位等效吗?
  • 第一阶段 i
  • 在第二个字节 (i=1) 上工作时,相位为 1 时只会进行一次清除,下一次相位为 1 时,它将处理第 5 个字节。
  • 看起来它每 4 个字节移动它们,然后存储到 3 个字节。例如将 16 个字节压缩成 12 个。
【解决方案2】:

我不完全确定,但代码似乎正在重新排列每个字节中的半字节并翻转它们(因此 0xF0 变为 0x0F)。它可能正在尝试压缩或加密字节 - 没有代表性的输入很难分辨。

关于函数中发生的不同事情:

  • 除以 4 与右移两次相同 (&gt;&gt; 2)
  • 除以 16 与右移四次相同 (&gt;&gt; 4)
  • 乘以 4 与左移两次相同 (&lt;&lt; 2)
  • 乘以 16 与左移四次相同 (&lt;&lt; 4)

这些部分从半字节重构一个字节,第一个半字节放在高位部分,第二个放在低位:

(byte)((16 * nibble1) + nibble2)

因此,如果nibble10x0F 并且nibble20x0C,则该运算导致nibble1 左移4,得到0xF0,然后添加nibble2,得到@ 987654335@.

【讨论】:

  • 第一阶段 i
  • @Creepy Gnome - 我同意,它确实显得多余。可能是代码开发过程中留下的工件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 2014-05-15
相关资源
最近更新 更多