2010-06-26 73 views
2

我對使用這種方法完成的工作感到困惑。它似乎試圖將字節分解爲半字節,並用其他字節的半字節重新組裝半字節以形成新字節,然後返回一個新的字節序列。但是,我沒有想到,你可以使用模數和減法和除法從一個字節中取出半字節,也不需要用簡單的乘法和加法重新組合它們。請幫忙弄清楚這個C#方法在做什麼?

我想更好地理解這個方法的工作原理以及它在做什麼,所以我可以得到一些關於它的評論,然後看看它是否可以被轉換,以使用更多更多的標準方法來琢磨字節和如果可能的話,甚至可以利用.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(); 
} 
+0

只是一個音符 - 除以4與'>> 2'相同,除以16與'>> 4'相同。乘以它們是同樣的左移。 – Oded 2010-06-26 19:05:14

+0

Gnome - 在前4遍(前四個字節)中,'i <4'爲真。所以,它似乎放棄了前4個結果。 – Oded 2010-06-26 19:22:28

+0

切換一個單獨維護的相位變量而不是僅僅切換我的mod是第一個跡象,這段代碼的其餘部分可能會讓事情變得困難。 – 2010-06-26 19:22:33

回答

3

乘以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; 
+0

會有%4和%16的按位等效嗎? – 2010-06-26 19:15:46

+0

是的,見編輯答案 – driis 2010-06-26 19:21:01

+0

階段1中i <4的目的是什麼?爲什麼在添加之前清除newBytes?由於階段是如何計算的,這隻會發生一次,並不是真的需要? – 2010-06-26 19:22:38

2

我不完全確定,但代碼似乎是重新排列每個字節中的半字節並翻轉它們(因此0xF0變爲0x0F)。它可能試圖壓縮或加密字節 - 如果沒有有代表性的輸入就難以分辨。

在問候的不同的事物的函數發生:

  • 除以4是相同的一個右移兩次(>> 2
  • 除以16是相同的一個右移四次(>> 4
  • 乘以4是相同的一個leftshifting兩次(<< 2
  • Multiplyingby 16是相同的一個leftshifting四次(<< 4

這些部件重建從半字節一個字節,第一個半字節被置於較高階部分,所述第二在低階:

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

所以如果nibble10x0Fnibble20x0C,操作導致nibble1左移4,導致0xF0,則添加nibble2,導致0xFF

+0

階段1中i <4的目的是什麼?爲什麼在添加之前清除newBytes?由於階段是如何計算的,這隻會發生一次,並不是真的需要? – 2010-06-26 19:23:44

+0

@Creepy Gnome - 我同意,它確實顯得多餘。可能是代碼開發過程中遺留的一個工件。 – Oded 2010-06-26 19:36:09

相關問題