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

в 10:23, , рубрики: java, Алгоритмы, Программирование

В данной статье я расскажу о битовой операции 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 в программировании

Шифрование

Шифрование на основе операций 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);
	}

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

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

Узким местом такого шифрования является то, что зная часть зашифрованного текста можно с легкостью восстановить ключ и, соответственно, разшифровать весь текст. Поэтому в чистом виде он редко используется на практике, хотя его применяют как часть более сложных алгоритмов шифрования.
Интересно, что в свое время данный алгоритм использовался 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, не вошедшие в статью, рассказать о них.

Автор: fealsoft

Источник

Поделиться

* - обязательные к заполнению поля