Практика применения XOR в программировании

от автора

В данной статье я расскажу о битовой операции XOR (исключающее ИЛИ) и приведу наиболее интересные примеры ее применения на JAVA.

И так, XOR – операция, которая принимает значение «истина» только если всего один из аргументов имеет значение «истина».

image

XOR обладает следующими свойствами:

a XOR 0 = a
a XOR a = 0
a XOR b = b XOR a
(a XOR b) XOR b = a

В языке JAVA (а также в С, С++, C#, Ruby, PHP, JavaScript) операция обозначается символом «^».

Обмен значений переменных без использования дополнительной переменной

С использованием операции XOR можно реализовать обмен значений однотипных пременных без использования дополнительной переменной:

		int x = 5, y = 7;   		x = x^y; // x == 2 		y = x^y; // y == 5 		x = x^y; // x == 7 

или в более короткой записи:

		y ^= (x ^= y); 		x ^= y; 

Таким образом можно, например, реализовать быстрый реверс текстовой строки:

	  public static final String reverseWithXOR(String string) { 	        char[] array = string.toCharArray(); 	        int length = array.length; 	        int half = (int) Math.floor(array.length / 2); 	        for (int i = 0; i < half; i++) { 	            array[i] ^= array[length - i - 1]; 	            array[length - i - 1] ^= array[i]; 	            array[i] ^= array[length - i - 1];	 	        } 	        return String.valueOf(array); 	    }		   

Шифрование

Шифрование на основе операций XOR использует свойство:
(a XOR k) XOR k = a
где k – выступает в роли ключа

Простая реализация шифрования строки:

	public static byte[] encode(String pText, String pKey) { 		byte[] txt = pText.getBytes(); 		byte[] key = pKey.getBytes(); 		byte[] res = new byte[pText.length()];  		for (int i = 0; i < txt.length; i++) { 			res[i] = (byte) (txt[i] ^ key[i % key.length]); 		}  		return res; 	} 

и дешифрования:

	public static String decode(byte[] pText, String pKey) { 		byte[] res = new byte[pText.length]; 		byte[] key = pKey.getBytes();  		for (int i = 0; i < pText.length; i++) { 			res[i] = (byte) (pText[i] ^ key[i % key.length]); 		}  		return new String(res); 	} 

Попробуем зашифровать строку “Съешь ещё этих мягких французских булок, да выпей чаю.” И в качестве ключа возьмем слово “хабра”:

Узким местом такого шифрования является то, что зная часть зашифрованного текста можно с легкостью восстановить ключ и, соответственно, разшифровать весь текст. Поэтому в чистом виде он редко используется на практике, хотя его применяют как часть более сложных алгоритмов шифрования.
Интересно, что в свое время данный алгоритм использовался Microsoft для шифрования содержимого документов в Office 95.

Генератор случайных чисел XORShift

В 2003 году Джордж Марсаглия представил миру быстрый алгоритм генерации случайных чисел с использованием XOR – XORShift.

Одна из возможных его рализаций:

class XORShift {  	private long rnd;  	public XORShift(long rnd) { 		this.rnd = rnd; 	}  	public long getRandom() { 		this.rnd ^= (this.rnd << 21);  		this.rnd ^= (this.rnd >>> 35);  		this.rnd ^= (this.rnd << 4);  		return this.rnd; 	} } 

Тут “магические“ числа 21, 35 и 4 подобраны для генерации лучшей последовательности (полный период равен 264-1).
Проинициализировав генератор числом 1111111111 получим такую последовательность для первых 10 чисел:

39462749392662495
4596835458788324745
-7932128052244037525
-2502212788642280052
3288035714308340525
-8561046377475020727
-812160615072319265
-3869866974339671508
-7329504029400927428
3890915262874757420

В заключении просьба тем, у кого есть другие красивые примеры применения XOR, не вошедшие в статью, рассказать о них.

ссылка на оригинал статьи http://habrahabr.ru/post/183462/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *