XOR 異或的性質與應用總結

2021-10-09 04:08:12 字數 3961 閱讀 9475

下面的內容均來自於網路的收集和彙總。

異或的實質是按位模2加,簡單理解就是不進製加法如:

1⊕1 = 1^1 =0; 

1⊕0 = 1^0 =1; 

0⊕0 = 0^0 =0; 

按位模2加:

101 ^ 110 ^ 111 = 100

101

110111

--------

322%2

--------

100

交換律:a ^ b = b ^ a;

結合律:a ^ b ^ c = (a ^ b) ^ c =a ^ (b ^ c);

恒等律:a ^ 0 = a;

歸零律:a ^ a = 0;

自反性:a ^ b ^ b = a ^ 0 = a;

對於任意的 x: x ^ (-1) = ~x;

如果 a ^ b = c ,那麼 a ^ b = c,b ^ c = a;

a ^ b = (!a) ^ (!b)

(!a) ^ b = a ^ (!b) = !( a ^ b )

看看第6條(為簡單化,按8位計算):

關鍵是-1的二進位製碼是多少?

1的二進位製碼為00000001, -1 + 1 =0 ,所以可以推出 -1 的二進位製碼為:11111111

00000001 + 11111111 = 00000000, 最高位被溢位。

那麼 x ^ (-1) = x ^ (11111111) = ~x;

變數交換判斷兩個數是否相等排除偶次重複(奇偶性判斷)格雷碼(gray code)錯誤檢測-crc校驗錯誤檢測-奇偶校驗資訊加密偽隨機數產生雙向鍊錶連續交替訊號產生

1.變數交換

真的不太好理解,慎用。

int a = 0x01;

int b = 0x10;

a = a ^ b;

b = a ^ b;

a = a ^ b;

2.判斷兩個數是否相等如果兩個數相等,異或結果為0, 不等為1, 為啥不直接用 == 呢?

3. 排除偶次重複(奇偶性判斷)

由a ^ a = 0, 得a ^ b ^ b = a ^ 0 = a; 偶數次重複的數都會被異或成0

4.格雷碼(gray code)

在通訊上用的一種編碼方式,編碼的過程當中主要用到了異或。

5.錯誤檢測-crc校驗

看了很多,下面這個博主講得算是比較易懂的

6.錯誤檢測-奇偶校驗

就是檢測傳輸資料中二進位制位為1的個數的奇偶性,就是對傳輸的資料按位進行異或, 1的個數為奇數,奇偶檢驗為1, 當1的個數為偶數時,奇偶校驗位0,

還有一種變種,較lrc,(longitudinal redundancy check), 這種是按位元組(8位)進行異或,原理差不多。

7.資訊加密

由異或的性質:a ^ b ^ b = a ^ 0 = a;  假設要傳輸的資訊為a, 並約定傳送方和接收方的共同秘鑰為b, 

在傳送方,用秘鑰對資訊進行異或之後再進行傳送, 即傳送的資料為: a ^ b;

在接收方,收到的資料為 a ^ b, 那麼用秘鑰再進行一次異或, a ^ b ^ b = a , 就可以還原出原始資訊資料。

沒有秘鑰的人拿到的資料是亂碼。

8.偽隨機數產生

對最高的兩位數進行異或,然後左移一位,並把異或的結果放到第0位,最開始需要乙個種子數,這種方法產生出來的數列是沒有什麼規律的,看起來像是隨機數。

9.雙向鍊錶

看下面這個鏈結

10.連續交替訊號產生

int x = 0x01;

int y = 0x10;

for (int n = x; true; n ^= (x ^ y))

std::cout << n << " ";

1-1000放在含有1001個元素的陣列中,只有唯一的乙個元素值重複,其它均只出現

一次。每個陣列元素只能訪問一次,設計乙個演算法,將它找出來;不用輔助儲存空

間,能否設計乙個演算法實現?

解法一、將所有數加起來,減去1+2+...+1000的和。只是如果數列過大,則可能會導致溢位。

解法二、異或,將所有的數全部異或,得到的結果與1^2^3^...^1000的結果進行異或,得到的結果就是重複數。

乙個陣列存放若干整數,乙個數出現奇數次,其餘數均出現偶數次,找出這個出現奇數次的數?

解法同上

題目:給定乙個整數陣列 ,其中恰好有兩個元素只出現一次,其餘所有元素均出現兩次。 找出只出現一次的那兩個元素。

(1) 全部元素先通過一次異或操作,重複元素會被抵消,最後結果是兩個單次出現的元素的異或值;

(2) 第1步最後的結果是兩個不同元素的異或值,其必定存在某乙個二進位制位不為0, 打個比方第1步異或的結果為0x06, 也就是0000 0110, 其第1,和第2位不為0, 那麼我們可以取0x04 或者 0x02做為比較值,我們可以叫他 bitvalue 

(3) 根據(2)找到的二進位制位bitvalue,可以將原陣列分成兩個部分(a部分和b部分),a部分必定包含其中乙個不同的元素,而另乙個不同元素必定在另一部分b。

(4) 對於兩個部分a,b分別再次進行異或操作,即相當於 排除偶次重複 問題,最終可以得到兩個題解。

int main()

; int sum = 0;

for (int i = 0; i < t1.size(); i++)

int tmp = 0;

while (sum > 0)

tmp++;

sum = sum / 2;

} int bitvalue = 0x01 << tmp;

int one = 0, two = 0;

for (int i = 0; i < t1.size(); i++)

else

two ^= t1[i];

} std::cout << one << " " << two << std::endl;

std::cin.get();

return 0;

}

按位模3加

題目:給定乙個整數陣列 ,其中乙個元素只出現一次,其餘所有元素均出現三次。 找出只出現一次的那個元素。

解法:參考異或的操作,異或的操作可以排除掉偶數次的元素,異或的操作實質是什麼呢?其實就是開篇所說的按位模2加,

那麼我們可以推理出按位模3加,可以排除出現3次,6次,9次。。。等的的元素。

如 陣列 為

9  1001

9 1001

9 1001

5 0101

7 0111

7 0111

7 0111 +

--------------

3437

%3--------------

5 0101

關於異或(XOR)的有趣應用

異或是個非常有意思的東西,利用異或的性質我們可以做一些有意思的事情。異或加密解密 下面是乙個非常簡單的加密解密函式 public static string encryption string srcstring,char key return new string srcchars 給出測試 st...

異或運算的性質

異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。簡單理解就是不進製加法,如1 1 0,0 0 0,1 0 1。性質 1 交換律a b a b...

異或的性質和運算

異或是一種基於二進位制的位運算,用符號xor或者 表示,其運算法則是對運算子兩側數的每乙個二進位制位,同值取0,異值取1。它與布林運算的區別在於,當運算子兩側均為1時,布林運算的結果為1,異或運算的結果為0。簡單理解就是不進製加法,如1 1 0,0 0 0,1 0 1。性質1 交換律 2 結合律 3...