首次說明一下,這個演算法是針對位數為2^n的二進位制數的。
最近在搞modbus,要求使用偶檢驗。想起以前看過乙個效率很高的演算法,但具體的怎樣都想不起來,於是上google搜尋了一輪,終於找到當年看過的演算法了:
8位的資料d(d7~d0),他的演算法為:
d ^= d >>4;
d ^= d >>2;
d ^= d >>1;
d&=1;
最後d就是偶校驗的值了。
可能有的同學一時之間看不明白演算法的原理,這裡解釋一下吧。
首先從d裡面找兩個位d1和d0,而d1d0的偶校驗值e0=d1^d0,這個大家都明白的,然後d3和d2的檢驗值e1=d3^d2,同理還有e2=d5^d4以及e3=d7^d6;
e0=1時代表了d1和d0裡面有奇數個1,e1、e2和e3同理;
然後複習一下小學數學:奇數*奇數=奇數,偶數*奇數=偶數
如果e0和e1裡面有奇數個1,那麼d3~d0裡面就有奇數數個1,此時d3~d0的偶校驗值為1;
「如果e0和e1裡面有奇數個1」這句話的意思不就是求由e1和e0組成的兩位二進位制的偶校驗麼?而且當e1e0的偶校驗值f0=1時,對應的d3~d0的偶校驗值也為1。
同理,e3e2的偶校驗值f1=1時,對應的d7~d4的偶校驗值也為1;
繼續同理,由f1和f0組成的兩位二進位制的偶校驗g0=1時,對應的是e3~e0的偶校驗值為1,同時對應的d7~d0的偶校驗值為1。
於是求d7~d0的偶校驗值變成了求f1f0的偶校驗值。
那麼首先就要將d7~d0的8個位兩兩分組後在分別求異或,然後再將得出的值的4個位兩兩分組後分別異或,最後將得出的值的2個位進行異或,得到的值就是d7~d0的偶校驗值了。
而分組則不必是相鄰的,將d右移4位再和原來的d進行異或的話就簡單多了
d7——d3
d6——d2
d5——d1
d4——d0
如此類推,每次先進行右移,然後和原來的值異或,最終就能得到d的校驗值了;另外在計算的過程中,僅僅需要關注後面的位數就可以了,如第二次計算時,高4位會有一些資料,到最後高7位也會有資料的,但這些資料都已經沒有用了,所以最後只需要來乙個&1就可以l。
於是文章開頭的那段8位二進位制數的演算法為:
d ^= d >>4;
d ^= d >>2;
d ^= d >>1;
d&=1;
另外對於2^n位二進位制數,第一次右移(2^n)/2位後再異或,然後重複類似的計算n次就可以了。
2 N位二進位制數的奇偶校驗演算法
最近在搞modbus,要求使用偶檢驗。想起以前看過乙個效率很高的演算法,但具體的怎樣都想不起來,於是上google搜尋了一輪,終於找到當年看過的演算法了 8位的資料d d7 d0 他的演算法為 d d 4 d d 2 d d 1 d 1 最後d就是偶校驗的值了。可能有的同學一時之間看不明白演算法的原...
校驗演算法之二進位制反碼求和
ip icmp igmp tcp udp等協議的校驗和演算法都是相同的,演算法如下 在傳送資料時,為了計算數ip據報的校驗和。應該按如下步驟 1 把ip資料報的首部都置為0,包括校驗和字段。2 把首部看成以16位為單位的數字組成,依次進行二進位制反碼求和。3 把得到的結果存入校驗和字段中。在接收資料...
校驗演算法之二進位制反碼求和
ip icmp igmp tcp udp等協議的校驗和演算法都是相同的,演算法如下 在傳送資料時,為了計算數ip據報的校驗和。應該按如下步驟 1 把ip資料報的首部都置為0,包括校驗和字段。2 把首部看成以16位為單位的數字組成,依次進行二進位制反碼求和。3 把得到的結果存入校驗和字段中。在接收資料...