簡體   English   中英

從字節檢查偶校驗

[英]Check even parity from byte

我在Stackoverflow上找到了一段代碼,並根據需要對其進行了編輯。 來源: 如何檢查值是否具有偶數奇偶校驗或奇數校驗?

它就像一種魅力,但我無法理解它為什么起作用。

我嘗試將其寫出,例如字節0b01101101。

   01101101
   00000110
   -------- ^
   01101011
   00011010
   -------- ^
   01110001
   00111000
   -------- ^
   01001001

我的單元測試給出了答案; 1個

uint8_t check_even_parity(uint8_t value){
     value ^= value >> 4;
     value ^= value >> 2;
     value ^= value >> 1;

     return value & 1;
}

預期是 0嘗試寫出時的實際結果; 01001001

每個步驟組合兩個比特集L和R,以使L的奇偶校驗與R的奇偶校驗合並。 R最終具有與L + R最初相同的奇偶校驗。

在第1步中,我們取8位,並產生一個與8位奇偶校驗相同的4位數字。 在第2步中,我們產生與4具有相同奇偶性的2位數字。在最后一步中,我們產生與2與2具有相同奇偶性的1位數字。這意味着在三步中,我們得到具有相同奇偶性的一位平價為原價8。

讓我告訴你我的意思一次。

  1. 讓我們從第一步開始,其中L是左4位(0110),R是右4位(1101)。

     xxxx1101 (R) xxxx0110 (L) -------- xxxx1011 (R^L) 

    我已經走了,把每個數字的左半部分刪除。 這些位無關緊要。 您將了解為什么,隨着我們的前進:越來越少的位與每個步驟相關。

    L是偶數,R是奇數,這意味着L + R是奇數。 因此,R ^ = L應該使R具有奇校驗。 可以? 的確如此。 0110有兩個設置位,因此R ^ = 0110翻轉R的兩個位。 翻轉偶數位不會更改奇偶校驗。 R仍然是奇數

  2. 在第二步中,L是左2位(10),R是右2位(11)。

     xxxxxx11 (R) xxxxxx10 (L) -------- xxxxxx01 (L^R) 

    現在將六位輸出。 我們只關心每個數字中的兩位。

    這次L是奇數,R是偶數。 結合起來,L + R是奇數,因此這一次我們需要翻轉R的奇偶校驗。 R ^ = L可以嗎? 再次,確實如此。 L設置了奇數個位,因此對其進行異或運算將翻轉R的奇數個位,從而確保R的奇偶校驗被切換。 R變成奇數

  3. 在最后一步中,L和R分別為1位。

     xxxxxxx1 (L) xxxxxxx0 (R) -------- xxxxxxx1 (L^R) 

    L是1,R是0。就像前面的步驟一樣,我們希望R ^ = L是奇數,並且是。 R是奇數

精彩。 我們從奇數奇偶校驗的8位開始,通過成功地將兩個半部分合並在一起,我們得到了具有相同奇數奇偶校驗的1位。

我想提出一個可以給出一些直覺的隱喻:

想象一下,您面前有4張卡片,您需要將這些卡片堆積起來。 作為一個有兩只手的人,您可以同時在每只手中拿起一張牌,然后將它們放在另一只2頂上,然后拿起其中一對,再將其放在另一只上。

這會將2張牌堆疊4張牌。

現在,假設您需要堆放32張牌並擁有16手(或更多)。 您可以使用相同的技術:創建16堆2張紙牌,而不是8堆4張紙牌,4堆8張紙牌,2堆16張紙牌,最后是32張紙牌。

這將在5個移動中堆積32張牌。

現在,以處理器的能力將“ pile”替換為“ xor”,將“ cards”替換為“ bits”,並將“ hands”替換為“ capsule”。 在5次移位和異或運算中,您將數字的32位異或在一起,如果該數字具有奇偶校驗,則得到0,否則得到1。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM