Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XOR operation with two strings in java

How to do bitwise XOR operation to two strings in java.

like image 757
yasitha Avatar asked Feb 26 '11 11:02

yasitha


People also ask

Can we XOR two strings in Java?

Firstly, the string produced is not properly xor'd in the sense that you cannot get your original string back by xor'ing it with the key again (unless your key was guaranteed to be equal to or longer than the messages which would be very strange) making the code completely misrepresent the concept of xor'ing.

How do you get XOR of two strings?

Approach: The idea is to iterate over both the string character by character and if the character mismatched then add “1” as the character in the answer string otherwise add “0” to the answer string to generate the XOR string.

What is XOR of two numbers in Java?

Bitwise XOR (exclusive or) "^" is an operator in Java that provides the answer '1' if both of the bits in its operands are different, if both of the bits are same then the XOR operator gives the result '0'. XOR is a binary operator that is evaluated from left to right.

Can you do XOR in Java?

Java XOR is one of the Bitwise operators available in Java. The XOR ( aka exclusive OR) takes two boolean operands and returns true if they are different. The best use case of the XOR operator is when both the given boolean conditions can't be true simultaneously.


2 Answers

You want something like this:

import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.io.IOException;  public class StringXORer {      public String encode(String s, String key) {         return base64Encode(xorWithKey(s.getBytes(), key.getBytes()));     }      public String decode(String s, String key) {         return new String(xorWithKey(base64Decode(s), key.getBytes()));     }      private byte[] xorWithKey(byte[] a, byte[] key) {         byte[] out = new byte[a.length];         for (int i = 0; i < a.length; i++) {             out[i] = (byte) (a[i] ^ key[i%key.length]);         }         return out;     }      private byte[] base64Decode(String s) {         try {             BASE64Decoder d = new BASE64Decoder();             return d.decodeBuffer(s);         } catch (IOException e) {throw new RuntimeException(e);}     }      private String base64Encode(byte[] bytes) {         BASE64Encoder enc = new BASE64Encoder();         return enc.encode(bytes).replaceAll("\\s", "");      } } 

The base64 encoding is done because xor'ing the bytes of a string may not give valid bytes back for a string.

like image 149
user467257 Avatar answered Sep 21 '22 00:09

user467257


Note: this only works for low characters i.e. below 0x8000, This works for all ASCII characters.

I would do an XOR each charAt() to create a new String. Like

String s, key;  StringBuilder sb = new StringBuilder(); for(int i = 0; i < s.length(); i++)     sb.append((char)(s.charAt(i) ^ key.charAt(i % key.length()))); String result = sb.toString(); 

In response to @user467257's comment

If your input/output is utf-8 and you xor "a" and "æ", you are left with an invalid utf-8 string consisting of one character (decimal 135, a continuation character).

It is the char values which are being xor'ed, but the byte values and this produces a character whichc an be UTF-8 encoded.

public static void main(String... args) throws UnsupportedEncodingException {     char ch1 = 'a';     char ch2 = 'æ';     char ch3 = (char) (ch1 ^ ch2);     System.out.println((int) ch3 + " UTF-8 encoded is " + Arrays.toString(String.valueOf(ch3).getBytes("UTF-8"))); } 

prints

135 UTF-8 encoded is [-62, -121] 
like image 36
Peter Lawrey Avatar answered Sep 21 '22 00:09

Peter Lawrey