プログラミングでXORを使用する練習

この記事では、XORビット操作(排他的OR)について説明し、JAVAでのアプリケーションの最も興味深い例を提供します。



したがって、XORは、引数の1つのみが値「true」を持つ場合にのみ値「true」を取る操作です。



画像







XORには次のプロパティがあります。



XOR 0 = a

a XOR a = 0

a XOR b = b XOR a

(a XOR b)XOR b = a



JAVA言語(およびC、C ++、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); }
      
      







「これらのソフトフレンチロールをもっと食べて、お茶を飲みましょう」という行を暗号化してみましょう。そして、「habr」という言葉をキーに取ります。







このような暗号化のボトルネックは、暗号化されたテキストの一部を知っていると、キーを簡単に回復し、それに応じてテキスト全体を復号化できることです。 したがって、より複雑な暗号化アルゴリズムの一部として使用されますが、純粋な形では実際にはほとんど使用されません。

興味深いのは、かつてMicrosoftがこのアルゴリズムを使用してOffice 95のドキュメントのコンテンツを暗号化したことです。



XORShift乱数ジェネレーター



2003年、 George MarsagliaはXOR- XORShiftを使用した高速乱数生成アルゴリズムを世界に紹介しました



可能な実装の1つ:

 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が選択されています(全期間は2 64 -1です)。

番号1111111111でジェネレーターを初期化することにより、最初の10個の番号に対して次のシーケンスを取得します。



39462749392662495

4596835458788324745

-7932128052244037525

-2502212788642280052

3288035714308340525

-8561046377475020727

-812160615072319265

-3869866974339671508

-7329504029400927428

3890915262874757420



結論として、記事には含まれていない、XORの使用の他の美しい例がある人たちに、それらについて話をするようにお願いします。



All Articles