目次
ビット演算子「XOR(排他的論理和)」の使い方
XOR(排他的論理和)は、下記のように演算子の左辺・右辺のビットを比べた上で、同じ場合は 0 に、異なる場合は 1 にする演算子です。
- 1 XOR 1 = 0
- 1 XOR 0 = 1
- 0 XOR 1 = 1
- 0 XOR 0 = 0
XOR演算子は「^」で表せます。
例えば、22(0x16)と75(0x4B)の XOR は次のように計算できます。
0000 0000 0000 0000 0000 0000 0001 0110 = 22(0x16) 0000 0000 0000 0000 0000 0000 0100 1011 = 75(0x4B) --------------------------------------- 0000 0000 0000 0000 0000 0000 0101 1101 = 93(0x5D)
このように、演算子(XOR)の左辺と右辺の値をビット単位で比べ、同じ場合は0に、異なる場合は1になっています。
計算すると、93(0x5D)という値になりました。
その他のビット演算子の使い方
ビット演算子には、XOR 以外にもいくつか存在します。
ここでは、その他のビット演算子についても簡単に確認しましょう。
意味 | 演算子 |
---|---|
排他的論理和(XOR) | ^ |
論理積(AND) | & |
論理和(OR) | | |
反転(NOT) | ~ |
論理積(AND)
AND(論理積)は、下記のように演算子の左辺・右辺のビットを比べた上で、両方が 1 の場合に結果を 1 にする演算子です。
- 1 AND 1 = 1
- 1 AND 0 = 0
- 0 AND 1 = 0
- 0 AND 0 = 0
AND演算子は「&」で表せます。
例えば、22(0x16)と75(0x4B)の AND は次のように計算できます。
0000 0000 0000 0000 0000 0000 0001 0110 = 22(0x16) 0000 0000 0000 0000 0000 0000 0100 1011 = 75(0x4B) --------------------------------------- 0000 0000 0000 0000 0000 0000 0000 0010 = 10(0x02)
論理和(OR)
OR(論理和)は、下記のように演算子の左辺・右辺のビットを比べた上で、一方が 1 の場合に結果を 1 にする演算子です。
左辺・右辺ともに 0 の場合に、結果も 0 になる演算子とも言えます。
- 1 OR 1 = 1
- 1 OR 0 = 1
- 0 OR 1 = 1
- 0 OR 0 = 0
OR演算子は「|」で表せます。
例えば、22(0x16)と75(0x4B)の OR は次のように計算できます。
0000 0000 0000 0000 0000 0000 0001 0110 = 22(0x16) 0000 0000 0000 0000 0000 0000 0100 1011 = 75(0x4B) --------------------------------------- 0000 0000 0000 0000 0000 0000 0101 1111 = 95(0x5F)
反転(NOT)
反転(否定)は、演算子が 1 の場合に結果を 0 に、演算子が 0 の場合に結果を 1 にする演算子です。
AND演算子は「~」で表せます。
例えば、22(0x16)の NOT は次のように計算できます。
0000 0000 0000 0000 0000 0000 0001 0110 = 22(0x16) --------------------------------------- 1111 1111 1111 1111 1111 1111 1110 1001 = -23(0xFFFFFFE9)
Java XORのサンプルコード
では実際に、Javaで XOR の計算結果を確認しましょう。
サンプルコードは次の通りです。
■記述例 public class Main { public static void main(String[] args) throws Exception { int xor = 22 ^ 75; int and = 22 & 75; int or = 22 | 75; int not = ~22; System.out.println("XOR:22 ^ 75 = " + xor); System.out.println("AND:22 & 75 = " + and); System.out.println(" OR:22 | 75 = " + or); System.out.println("NOT:~22 = " + not); } }
上記のプログラムを実行すると、次の実行結果を得られます。
■実行結果 mbp:desktop potepan$ java Main XOR:22 ^ 75 = 93 AND:22 & 75 = 2 OR:22 | 75 = 95 NOT:~22 = -23
ここまでの説明であった計算結果と、同じになっているのがわかります。
XORでも用いる「boolean」について
XOR で各桁を比較する際の結果は必ず boolean型 になります。
ここでは、boolean型について少しおさらいしておきましょう。
Javaのboolean型は、「真偽値型」とも呼ばれ、値は「true」もしくは「false」のいずれかのデータのみが設定されるデータ型です。
boolean型に「null」を設定することはできず、必ず true か false が設定されます。
booleanは主に、条件によって処理を分岐させたい場合の判定として利用することが多いです。
そのため、Javaプログラミングにおいて利用する機会も多いと言えますね。
覚えておいて損のない仕組みです。
では実際に、Javaのサンプルコードで動きを確認してみましょう。
■記述例 import java.util.*; public class Main { public static void main(String[] args) throws Exception { boolean bool = false; if(bool) { System.out.println("boolの値は「true」です"); } else { System.out.println("boolの値は「false」です"); } int number = 100; boolean isResult = number < 200; if(isResult) { System.out.println("isResultの値は「true」です"); } else { System.out.println("isResultの値は「false」です"); } } }
上記のプログラムを実行すると、次の実行結果を得られます。
■実行結果 mbp:desktop potepan$ java Main boolの値は「false」です isResultの値は「true」です
bool と isResult が true か false かによって、表示される文言を切り替えているのがわかります。
XORを使った暗号化について
XOR(排他的論理和)の性質を利用して暗号化も可能です。
仕組みとしては下記の通り。
- A(暗号化するもの) ^ B(暗号化するキー) = C(暗号化したもの)
- C ^ B = D(復元したもの)
- A = D
ここでは、参考までにJavaでXORを使った暗号化コードを紹介します。
import java.util.*; public class Main { public static void main(String[] args) throws Exception { String value = "排他的論理和"; String key = "演算子"; System.out.println("暗号化前:" + value); // value を暗号化する byte[] byteEncodeArray = encode(value.getBytes(), key); value = new String(byteEncodeArray); System.out.println("暗号化後:" + value); // 暗号化した value を復元する byte[] byteDecodeArray = decode(value.getBytes(), key); value = new String(byteDecodeArray); System.out.println("復元後:" + value); } //////////// // 暗号化する関数 //////////// private static byte[] encode(byte[] src, String key) { byte[] byteKeyArray = new byte[0]; byte[] byteEncArray = new byte[src.length]; while(byteKeyArray.length < src.length) { byteKeyArray = (new String(byteKeyArray) + key).getBytes(); } for (int i = 0; i < src.length; i++) { byteEncArray[i] = (byte)(src[i]^byteKeyArray[i]); } return byteEncArray; } //////////// // 復元する関数 //////////// private static byte[] decode(byte[] src, String key) { return encode(src, key); } }
上記のプログラムを実行すると、下記のような結果になります。
■実行結果 mbp:desktop potepan$ java Main 暗号化前:排他的論理和 暗号化後:27>? 復元後:排他的論理和
「排他的論理和」という言葉を、「演算子」というキーで「27>?」に暗号化できました。
復元処理を行うことで、再び「排他的論理和」という言葉に戻せています。
つまり、XORには以下のような性質があります。