[英]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。
讓我告訴你我的意思一次。
讓我們從第一步開始,其中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仍然是奇數 。
在第二步中,L是左2位(10),R是右2位(11)。
xxxxxx11 (R) xxxxxx10 (L) -------- xxxxxx01 (L^R)
現在將六位輸出。 我們只關心每個數字中的兩位。
這次L是奇數,R是偶數。 結合起來,L + R是奇數,因此這一次我們需要翻轉R的奇偶校驗。 R ^ = L可以嗎? 再次,確實如此。 L設置了奇數個位,因此對其進行異或運算將翻轉R的奇數個位,從而確保R的奇偶校驗被切換。 R變成奇數 。
在最后一步中,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.