Q & A
비트 XOR 연산자는 어디에 사용하나요?
비트 XOR 연산자는 간단한 암호화에 사용됩니다.
int plane = 100; // 평문 int key = 57; // 암호키 int encrypted = plane ^ key; // 암호화 printf("%d\n", encrypted); // 93 int decrypted = encrypted ^ key; // 복호화 printf("%d\n", decrypted); // 100: 평문 plane과 같음
평문과 암호키를 비트 XOR 연산하면 암호화된 값이 나옵니다. 이 암호화된 값과 암호키를 비트 XOR 연산하면 암호화된 값이 복호화됩니다(평문이 됨). 즉, XOR은 다음과 같은 특성을 가집니다.
- a ^ b = c
- c ^ b = a
- c ^ a = b
참고로 XOR 암호화는 너무 간단하게 풀리기 때문에 실무에서는 거의 사용하지 않으며 안전성이 검증된 암호화 알고리즘(AES, RSA 등)을 사용합니다.
XOR의 특성을 활용하면 임시 변수를 사용하지 않고 두 변수의 값을 바꿀 수도 있습니다. 먼저 임시 변수를 사용하여 두 변수의 값을 바꾸는 코드입니다.
int a = 10; int b = 20; int temp; // 임시 변수 temp = a; a = b; b = temp; // a와 b의 값이 서로 바뀜 printf("%d\n", a); // 20 printf("%d\n", b); // 10
이번에는 임시 변수 없이 비트 XOR 연산자를 세 번 사용해서 두 변수의 값을 바꿉니다.
int a = 10; int b = 20; a = a ^ b; b = a ^ b; a = a ^ b; // a와 b의 값이 서로 바뀜 printf("%d\n", a); // 20 printf("%d\n", b); // 10
나누기 2를 하는 좋은 방법은 무엇인가요?
2의 거듭제곱을 할 때 시프트 연산을 사용했습니다. 그렇다면 2를 나눌 때도 시프트 연산이 좋을까요?
a = a >> 1; // 시프트 연산 b = b / 2; // 나누기 연산
사실 이 두 연산은 서로 다릅니다. 예를 들어 음수에 시프트 연산과 나누기 연산을 해보면 결과가 다르게 나옵니다.
-5 >> 1 = -3 -5 / 2 = -2
숫자를 비트로 다룰 때는 비트 연산자를 사용하고, 그냥 숫자를 다룰 때는 나누기 연산자를 사용해야 합니다.