Page 1 of 1

## Secret Code VI - The XOR operator Second step in the computer era Rate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=192155&amp;s=bed25901075e70582444aa0c3761be2d&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 pbl

• There is nothing you can't do with a JTable

Reputation: 8378
• Posts: 31,956
• Joined: 06-March 08

Posted 26 September 2010 - 04:28 PM

Before going into the RSA stuff one thing to really understand is the use of the XOR operator.

Following the tutorial about Swap and Rotate here is another one using the XOR operator.

As usual a console application named Xor.java is provided.
As is the previous tutorial a class CharAndBits.jave is provided for printing (both at the console and in the GUI) the bits representation of every byte.

This version of CharAndBits has some improvments compare the previous version coming from Secret Code V. You can take it and overload the previous copy you had if you cut & pasted the code from the previous tutorial, our code from SwapAndRotate will still works.

As usual we present a console version:
- Xor.java which has in its main() method unit test
- XorGui.java that uses the preceeding one and dynamically show the encryption/decryption processes

CharAndBits.java
```/**
* A class for easy representation of all ASCII character on the console
* and on GUIs.
* This class contains the binary representation of the char it represents
* If the char is prinatble it returns its ASCII representation else it returns '.'
*/
public class CharAndBits implements Comparable<CharAndBits> {

// the character by itself
private char theChar;
// the char to display (will be '.' if not printable
private char toAscii;
// it's int value used for bitwise operation
private int intValue;
// its 8 bits representation as a String
private String binaryStr;
// its 8 bits representation as 8 char containing '0' or '1'
private char[] binaryChar;
// its 8 bits representation as 8 int containing 0 or 1
private int[] binaryInt;

/**
* Constructor that receives the char as parameter
*/
public CharAndBits(char theChar) {
// save it
this.theChar = theChar;
// test if it is printable if it is the case use it else use '.'
if(isPrintable())
toAscii = theChar;
else
toAscii = '.';
// get it's int value
intValue = theChar;
intValue &= 0xFF;				// ok we just support the 255 Ascii characters
// convert to binary char and int
binaryChar = new char[8];
binaryInt = new int[8];
int temp = intValue;
for(int i = 7; i >= 0; i--) {
binaryInt[i] = temp & 1;
binaryChar[i] = (char) binaryInt[i];
binaryChar[i] += '0';
temp >>>= 1;
}
// and the whole String
binaryStr = new String(binaryChar);
}

/**
* return true of false depending if the char is printable (GUI or console)
*/
public boolean isPrintable() {
return !Character.isISOControl(theChar);
}

/**
* Returns the binary representation of this char
*/
public String toBinaryString() {
return binaryStr;
}
/**
* returns a printable version of an encoded String
*/
public static String toAsciiString(String encoded) {
// convert the String to an array of CharAndBits
CharAndBits[] array = newCharAndBitsArray(encoded);
// prepare an array of char[] of the same length
char[] digit = new char[encoded.length()];
// get the printable version of every char
for(int i = 0; i < encoded.length(); i++)
digit[i] = array[i].toAscii;
// return a String out of it
return new String(digit);
}
/**
* Get the printable version of this char
*/
public char getPrintableChar() {
}

/**
* Returns the int value of this char
*/
public int getIntValue() {
return intValue;
}

/**
* Getter for the binary char
*/
public char[] getBinaryChar() {
return binaryChar;
}
/**
* To test 2 EasyCharacter for equality
*/
public boolean equals(CharAndBits other) {
return compareTo(other) == 0;
}
/**
* Used to sort an array of EasyCharacter
*/
public int compareTo(CharAndBits other) {
return intValue - other.intValue;
}

/**
* A static method to get an array of EasyCharacter from a String
* (so the caller does not have to perform the loop himself)
*/
public static CharAndBits[] newCharAndBitsArray(String str) {
// if str is null return a 0 length array of EasyCharacter
if(str == null)
return new CharAndBits[0];
// convert String received as parameter as an array of char
char[] digit = str.toCharArray();
CharAndBits[] array = new CharAndBits[digit.length];
for(int i = 0; i < digit.length; i++)
array[i] = new CharAndBits(digit[i]);
return array;
}
/**
* A static method to get a printable String from an array of EasyCharacter[]
* to display at the console or in a GUI
*/
public static String getMsgString(CharAndBits[] array) {
StringBuilder sb = new StringBuilder(array.length);
// copy our EasyCharacter into the buffer
for(CharAndBits ea : array)
sb.append(ea.toAscii);		// printable version
// return the StringBuilder as a String
return sb.toString();
}

/**
* To perform the Xor between 2 arrays of EasyCharcter
* and return an String with the 2 arrays XORed
* The first parameter is the message, the second the key
* The array returned will have the size of the message
* if the key is smaller than the message a wrapAround will occur
*/
public static String xorArray(CharAndBits[] msg, CharAndBits[] key) {
// check for null or no length message
if(msg == null || msg.length == 0)
return "";								// return String of 0 length
// create the digit to hold the xored value
int msgLen = msg.length;
StringBuilder sb = new StringBuilder(msgLen);

// check for null or empty key in that case just return a copy of our message
if(key == null || key.length == 0) {
for(CharAndBits ea : msg)
sb.append(ea.theChar);
return sb.toString();
}
// get length of the key and create new array
int keyLen = key.length;
// loop to perform the XOR between each element of the msg array and the key with wrap around
for(int i = 0; i < msgLen; i++) {
int val = msg[i].intValue ^ key[i % keyLen].intValue;
sb.append((char) val);
}
// convert the StringBuilder array to a String
return sb.toString();
}

/**
* static methods that return a String representation in binary of an array of char
*/
public static String toBinaryString(String str) {
}
public static String toBinaryString(char[] digit) {
// use a StringBuilder to append the binary represenation
StringBuilder sb = new StringBuilder(digit.length * 9);    // * 9 for the blank space
for(char c : digit) {
CharAndBits ea = new CharAndBits(c);
// append the 01010101010
sb.append(ea.toBinaryString());
sb.append(' ');
}
// return as a String
return sb.toString();
}
}

```

The console version of the encoding/decoding algorithm using XOR

```import java.util.Scanner;

/**
* Secret Code VI
*
* If you have played with tutorial Secret Code V (SwapAndRotate) you will have seen as message can now
* be considered as a big number instead of different digits or even symbols.
*
* Before going to the complete RSA encoding/decoding system let us play with more basic encoding/decoding
* mechanisms using binary code.
*
* Ok so what's so special with characters on a computer ?  It is because characters are represented by
* a serie of bits.  We will stay with plain Ascii for now for simplicity.
*
* Imagine the message "Hello". The Ascii representation of Hello in 8 bits bytes is
*    H        e        l        l        o
* 01001000 01100101 01101100 01101100 01101111
*
* In the Secret Code V tutorial we have seen how to swap and rotate bits in a message.
*
* Now most encryptions rely on the bitwise operator XOR property that says that
* if b and c are bits fields
* a = b XOR c
* a XOR c gives back b and
* a XOR b gives back c
* The XOR operator in Java is ^ and can be applied to integer.
*
* Let us verify this assertion with all possible versions of 0 and 1
* Message:           1100
* Key:               1010
*                    ----
* XOR Msg and Key:   0110  this is the encrypted message
*
* Now let's XOR the encrypted message with the key
* Encrypted message: 0110
* Key:               1010
*                    ----
* XOR                1100  back to the original message
*
* One big thing about this mechanism is that the process to encode is exactly the same
* as the one to decode
* we just XOR with the key both the message to encode and the message to decode.
* No need for a Encode() method and a Decode() method. The same one is used
* and the method does not need to know if it is actually encoding or decoding.
*
* In this tutorial we will just play with this XOR feature to encode/decode messages
* For that we will use a key if the key is smaller than the message we just repeat it
* So the encode "Hello world" with the key "Dave" we will use as key
*               "DaveDaveDav"
* The following console application uses this technique
* As in the previous tutorial we will used the CharAndBits class to output as a series of 0 and 1
* the bits contained in a character.
*
* If you have already the CharAndBits.java class/file from the previous tutotial, take this
* new one, it has new functionnalities. The new version still support the code from
* tutorial V so you can erase the old one, take the new one, and the code of SwapAndRotate will
* still work.
*
*/
public class Xor {

// the key used for encript/decript
private String key;

/**
*  Constructor that receives the key as parameter
*/
public Xor(String key) {
// call common method to set the initial key or change it
setKey(key);
}

/**
* Method to set the original key and permit to change it on the fly
*/
public void setKey(String key) {
// avoid null key
if(key == null)
key = "";
// save it
this.key = key;

}

/**
* Method that encode/decode a message based on the registered key
* Contrary to other coding mechanisms seen in the previous tutorials
* the mechanism to encode and decode is the same wo we do not need
* an encode and a decode method. The same method can be used for
* both operations
*/
public String encodeDecode(String msg) {
// validate that the message is not null or length == 0
// if it is the case, just return the original message
if(msg == null || msg.length() == 0)
return msg;
// if the key is "" we return the original message
if(key.length() == 0)
return msg;
// make an array of CharAndBits from both the message and the key
CharAndBits[] m = CharAndBits.newCharAndBitsArray(msg);
CharAndBits[] k = CharAndBits.newCharAndBitsArray(key);
// and call the method that performs the XOR operation
String encodeDecodeValue = CharAndBits.xorArray(m, k);
return encodeDecodeValue;
}

/**
* A quick and dirty method to return the key duplicated enough times
* so it will have the length of the message.
* This is just for printing purpose only both in the main() method and in the GUI.
* The method is not involved in the encoding/decoding process itself
*/
public String dupKey(int msgLen) {
// if the key is invalid no
if(key.length() == 0)
return "";
String dup = key;
while(dup.length() < msgLen)
dup += key;
return dup.substring(0, msgLen);
}

/**
* To test the class
*/
public static void main(String[] args) {

//-------- unit tests to see that the whole thing works --------
String msg = "DreamInCode";
String key = "dave";
// create the Xor object
Xor xor = new Xor(key);

// for print out purpose only get the key used (it will be as log as the message)
String dupKey = xor.dupKey(msg.length());
System.out.println("The original message is: \"" + msg + "\" the key used will be \"" + dupKey + "\"");
// call the utility method for binary representation of the message
String msgInBin = CharAndBits.toBinaryString(msg);
System.out.println(msgInBin);

// the repeated key in binary
String keyInBin = CharAndBits.toBinaryString(dupKey);
System.out.println(keyInBin);
// build a series of -------
char[] dash = new char[msgInBin.length()];
for(int i = 0; i < msgInBin.length(); i++)
dash[i] = '-';
// print the serie of ------
System.out.println(new String(dash));

// encode the message which is the result of the XOR
String encoded = xor.encodeDecode(msg);
// display the encoded bits
String encodedInBinary = CharAndBits.toBinaryString(encoded);
System.out.println(encodedInBinary);
// display what is printable out of it
System.out.println("The encrypted message is: \"" + CharAndBits.toAsciiString(encoded) + "\"");

// now the reverse process
System.out.println();
System.out.println("The encoded message XORed with the key");
System.out.println(encodedInBinary);			// encoded message
System.out.println(keyInBin);					// key in binary
System.out.println(new String(dash));           // the ------------

// decode the encoded message calling the SAME method
String decoded = xor.encodeDecode(encoded);
// display the decoded message
System.out.println(CharAndBits.toBinaryString(decoded));
System.out.println("The decoded message is \"" + decoded + "\" is it the same as \"" + msg + "\": " + msg.equals(decoded));
// ----------------------------- end of unit tests ---------------------------------

// Now prompting the user
Scanner scan = new Scanner(System.in);
String userKey;
// get a key of length > 0 from the user
System.out.println();
do {
System.out.print("Enter the key to use: ");
userKey = scan.nextLine();
} while(userKey.length() == 0);

// build the Xor object
Xor userXor = new Xor(userKey);
// get the message to encode/decode
System.out.print("Enter message to encode: ");
String userMsg = scan.nextLine();

// generate the key that will be used for print out purpose only
String userDupKey =  userXor.dupKey(userMsg.length());
System.out.println("The original message is: \"" + userMsg + "\" the key used will be \"" + userDupKey + "\"");
// call the utility method for binary representation of the message
String userMsgInBin = CharAndBits.toBinaryString(userMsg);
System.out.println(userMsgInBin);

// the repeated key in binary
String userKeyInBin = CharAndBits.toBinaryString(userDupKey);
System.out.println(userKeyInBin);
// build a series of -------
char[] userDash = new char[userMsgInBin.length()];
for(int i = 0; i < userMsgInBin.length(); i++)
userDash[i] = '-';
// print the serie of ------
System.out.println(new String(userDash));

// encode the message which is the result of the XOR
String userEncoded = userXor.encodeDecode(userMsg);
// display the encoded bits
String userEncodedInBinary = CharAndBits.toBinaryString(userEncoded);
System.out.println(userEncodedInBinary);
// display what is printable out of it
System.out.println("The encrypted message is: \"" + CharAndBits.toAsciiString(userEncoded) + "\"");

// now the reverse process
System.out.println();
System.out.println("The encoded message XORed with the key");
System.out.println(userEncodedInBinary);			// encoded message
System.out.println(userKeyInBin);					// key in binary
System.out.println(new String(userDash));           // the ------------

// decode the encoded message calling the SAME method
String userDecoded = userXor.encodeDecode(userEncoded);
// display the decoded message
System.out.println(CharAndBits.toBinaryString(userDecoded));
System.out.println("The decoded message is \"" + userDecoded + "\" is it the same as \"" + userMsg + "\": " + userMsg.equals(userDecoded));

}

}

```

And now the GUI XorGui.java
This GUI is also a good example on how to use JTable with variable number of columns

```import java.awt.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

/**
* A GUI that use the Xor class to encode/decode messages
* In this GUI we cannot prompt for a String to decode as XOring bits
* in byte may generate characters that may (most probably) not be displayable
*
* The GUI display the binary form of each letter in the message
* their coded representaion after the XOR operation
* This GUI is greatly inspired from the SwapAndRotateGui of Secret Code V tutorial
*
* Note that if a letter of the message and the corresponding letter of the key are equal
* the encrypted letter is 00000000
* If message is ABC and key 123 the encrypted versions should be the same :-)
*/
public class XorGui extends JFrame {

private static final long serialVersionUID = 1L;

// the Xor class to encode/decode
private Xor xor;

// the key to use
private JTextField keyText;
// the letter of the key for every letter in the key
private char[] longKey;
// The message to encode
private JTextField clearTextIn;

// the original message
private char[] msgChar = new char[0];
// the encoded messages
private char[] msgEncoded;
// the decoded messages that should be the same as msgChar
private char[] msgDecoded;

// The JTable shown in the CENTER region
private JTable table;
private MyModel myModel;
private TableColumnModel colModel;

// Its panel
private JPanel centerPanel;
// the first column of the jTable
private static final String[] firstCol = {"Message", "Msg Bin", "Key Bin", "XOR Encoded", "Encoded Ascii", "Key Bin", "XOR Decoded", "Decoded Ascii"};
// mnemonic for more descriptive values in the AbstractModel
private static final int ORIG = 0, ORIG_BIN = 1, KEY1_BIN = 2, CRYPTED_BIN = 3, CRYPTED = 4, KEY2_BIN = 5, DECRYPTED_BIN = 6, DECRYPTED = 7;

/**
* Constructor
*/
XorGui() {
super("XOR encoding/decoding");
// we will use a BorderLayout to store our GUI component
setLayout(new BorderLayout());

// the Xor object init the key to ""
xor = new Xor("");
longKey = xor.dupKey(0).toCharArray();
// the Listener the key changes
DocumentListener dc = new KeyListener();
// The NORTH region will contain a JPanel where the key and the message can be entererd
JPanel north = new JPanel(new GridLayout(5, 1, 2, 2));
// the key
keyText = new JTextField(50);
// the message
north.add(createCenteredLabel("Enter the message to encode here"));
clearTextIn = new JTextField(50);
// a gap
// add this panel to the top of the screen

// in the CENTER region of the frame we will put a JTable containing all the
// encrypted/decripted bits
myModel = new MyModel();
table = new JTable(myModel);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
colModel = table.getColumnModel();

centerPanel = new JPanel(new BorderLayout());

// standard operation to show the JFrame
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(30, 30, 700, 320);
setVisible(true);

// to set the size of column 1
}

/**
* A method to create a JLabel with foreground color Blue and with text centered
*/
private JLabel createCenteredLabel(String text) {
JLabel label = new JLabel(text);
label.setHorizontalAlignment(SwingConstants.CENTER);
label.setForeground(Color.BLUE);
return label;
}

/**
* The key has changed
*/
private void updateKeyString() {
// update key in the Xor object from the key JTextField
xor.setKey(keyText.getText());
// update the encoding process
}

/**
* To update the string to be coded
*/
// get the text of the message to encode from the JTextField
String line = clearTextIn.getText();
// make the char[] array out of it to be displayed in the JTable
msgChar = line.toCharArray();
// generate (for display purpose only) the key that will be used for every character
longKey = xor.dupKey(line.length()).toCharArray();
// build the encrypted message
String encoded = xor.encodeDecode(line);
// in a char[] for display purpose
msgEncoded = encoded.toCharArray();
// build the decrypted char[]
msgDecoded = xor.encodeDecode(encoded).toCharArray();
// inform the model that the table contain changed
myModel.fireTableStructureChanged();
myModel.fireTableDataChanged();
// set the size of the column when a new column is added lets set it's size
int actualColumnCount = msgChar.length + 1;
for(int i = 0; i < actualColumnCount; i++) {
TableColumn tc = colModel.getColumn(i);
tc.setPreferredWidth(100);
tc.setMinWidth(100);
}
}

/**
* To start the GUI
*/
public static void main(String[] args) {
new XorGui();
}

/**
* A listener to be informed whenever the JTextField of the clear text is changed
*/
private class ClearListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent arg0) {
}
@Override
public void insertUpdate(DocumentEvent arg0) {
}
@Override
public void removeUpdate(DocumentEvent arg0) {
}
}

/**
* A listener to be informed whenever the JTextField of the SWAP or ROTATE key is changed
*/
private class KeyListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent arg0) {
updateKeyString();
}
@Override
public void insertUpdate(DocumentEvent arg0) {
updateKeyString();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
updateKeyString();
}
}

/**
* A class that extends AbstractTableModel to povide the binary representation
* of every cell of the JTable in the center panel
*/
private class MyModel extends AbstractTableModel {

private static final long serialVersionUID = 1L;

// the number of columns is the length of the message + the first column
public int getColumnCount() {
return  msgChar.length + 1;
}

// name of each colum (first one is empty)
public String getColumnName(int column) {
// if column 0 we return the hardcode "Steps"
if(column == 0)
return "Steps";

// skip first column
--column;
// verify that we have data for this column
if(column >= msgChar.length || column >= longKey.length)
return "";

// OK generate its title which is the letter of the key used
return "#" + (column+1) + " Key: \"" + longKey[column] + "\"";
}

// return the row count
public int getRowCount() {
// it is the length of our first column
return firstCol.length;
}

// the JTable want's to know what to print there
public Object getValueAt(int row, int col) {
// for the first column we just return the header
if(col == 0)
return firstCol[row];
--col;
// validate first the col it should be contained in the mesage
if(col >= msgChar.length)
return "";

// the CharAndBits to display init to null we will check it later
CharAndBits cab = null;

// depending of the column display the correct text field
switch(row) {
// the original message we juts return the character of that row
case ORIG:
return "      >" + msgChar[col] + "<";
// the binary stransaltion of that letter
case ORIG_BIN:
cab = new CharAndBits(msgChar[col]);
break;
// the binary representation of the key (same one at both row)
case KEY1_BIN:
case KEY2_BIN:
if(col >= longKey.length)
return "";
cab = new CharAndBits(longKey[col]);
break;
// the binary representation of the encrypted letter of the message
case CRYPTED_BIN:
cab = new CharAndBits(msgEncoded[col]);
break;
// the ASCII representation (if it exists) of this letter of the message
case CRYPTED:
CharAndBits c = new CharAndBits(msgEncoded[col]);
if(c.isPrintable())
return "      >" + c.getPrintableChar() + "<";
else
return "      -";
// the decrypted message back should be the same of ORIG_BIN
case DECRYPTED_BIN:
if(col >= msgDecoded.length)
break;
cab = new CharAndBits(msgDecoded[col]);
break;
// the letter of the message back into Ascii
case DECRYPTED:
return "      >" + msgDecoded[col] + "<";
}
// common formatting the binary string followed by the printable version of the char
// unless not defined yet due to the way the GUI refresh the JTable
if(cab == null)
return "";
return cab.toBinaryString();
}

}

}

```

Have fun

Is This A Good Question/Topic? 0

## Replies To: Secret Code VI - The XOR operator

### #2 nasrul

Reputation: 0
• Posts: 8
• Joined: 08-February 11

Posted 13 March 2011 - 09:35 AM

Hello sir,im new to this type of encryption.Is it this XOR function using LFSR?if it's use LFSR,can you show where is the function that do the LFSR.really2 eager to know.Thanks

Edited by macosxnerd101: Please do NOT quote the person above you, especially when their post is extremely long.