Пожалуйста, помогите понять, что делает этот метод C #? - PullRequest
2 голосов
/ 26 июня 2010

Я немного сбит с толку относительно того, что достигается этим методом.Кажется, что он пытается разбить байты на кусочки и собрать кусочки с кусочками из других байтов, чтобы сформировать новые байты, а затем вернуть новую последовательность байтов.

Однако я не думал, что вы могли бы взять клевыиз байта, используя модуль и вычитание и деление, и не собирать их с помощью простого умножения и сложения.

Я хочу лучше понять, как работает этот метод и что он делает, поэтому я могу получить некоторые комментарии по немуа затем посмотреть, можно ли его преобразовать, чтобы придать ему больше смысла, используя более стандартные методы пощипывания байтов, и даже по возможности использовать преимущества .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();
}

Ответы [ 2 ]

3 голосов
/ 26 июня 2010

Умножение на 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;
2 голосов
/ 26 июня 2010

Я не совсем уверен, но код, кажется, переставляет полубайты в каждом байте и переворачивает их (поэтому 0xF0 становится 0x0F).Возможно, он пытается сжать или зашифровать байты - трудно сказать без репрезентативного ввода.

Что касается различных вещей, происходящих в функции:

  • Деление на 4 одинаковосмещение прав в два раза (>> 2)
  • Деление на 16 - это то же самое, смещение прав в четыре раза (>> 4)
  • Умножение на 4 - это то же самое, что и смещение влево дважды (<< 2)
  • Умножение на 16 - это то же самое, что и сдвиг влево четыре раза (<< 4)

Эти части восстанавливают байт из полубайтов, первый полубайт размещается в части более высокого порядка, второй - внижний порядок:

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

Так что, если nibble1 равно 0x0F и nibble2 равно 0x0C, операция приводит к сдвигу влево nibble1 на 4, в результате чего 0xF0затем добавляется nibble2, в результате чего 0xFF.

...