How to do bitwise XOR operation to 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.
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.
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.
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.
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.
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With