byte to char conversion in one time pad encryption program

i'm writing a simple one time pad encryption program, but having one last little problem.  I have a text file that contains the string "GinaTravis326" (w/o the quotes of course).   My dilemma is with the output.  Here are the steps I'm taking ...

(1)  pulled in the byte values into a plain text byte array (pText)
      **result:
          pText = [105, 110, 97, 84, 114, 97, 118, 105, 115, 51, 50, 54]

(2)  generated bits and stored them in a stringbuffer (bitSB); cycled through stringbuffer to create pad byte array via:
      (bitstring is a String variable, twoscomp computes the two's complement, and counter is an int initialized to 0)

for (int i=0; i<bitSB.length(); i+=8);
{
     bitstring = bitSB.substring(i, i+8);
     pad[counter++] = (byte)Integer.parseInt(twoscomp(bitstring));
}

    **result:
       pad = [31, -53, -81, -11, -56, 65, 24, 59, -47, 22, -127, -112, 18]

(3) I then use the bitwise XOR to populate a cipher text byte array (cText) & write to an encrypted output file via:

PrintWriter outfile = new PrintWriter(new FileOutputStream(file));
int cnt = 0;
while (cnt < pad.length)
{
     cText[cnt] = (byte)(pText[cnt]^pad[cnt]);
     outfile.print((char)cText[cnt]);
     cnt++;
 }

     **result:
         cText = [88, -94, -63, -108, -100, 51, 121, 77, -72, 101, -78, -94, 36]

----> NOW DECRYPTING <------

(4)  like before, i pull in the byte values from the file (which should be synonymous with cText)
(5)  create the pad byte array like before based of the cText values this time rather than the pText ones
(6)  did the bitwise XOR like about in step 3, except this time:

while (cnt < pad.length)
{
      pText[cnt] = (byte)(cText[cnt]^pad[cnt]);
      outfile.print((char)pText[cnt]);                    //this is not writing the correct characters to the decrypted file!
      cnt++;
}
                   
     **result:
         pText = [71, -12, -112, -54, -9, 114, 97, 118, -18, 115, -66, -81, 54]

When I cast the pText values back to (char) as shown above,
the decrypted file contains the string:
       G????rav?s??6
rather than
       GinaTravis326

It seems obvious to me that this is because of the negative values, but how do I account for this ???   How can I get the output to be correct???   Thanks !!!    

By the way, using the String(byte[], "UTF8").toCharArray() method is NOT an option.   Thanks again!

- Travis
trs28Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Tommy BraasCommented:
Do not use character based I/O. View everything as binary data.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
trs28Author Commented:
Could you elaborate on that a little bit ??  ...maybe with an example or something!   I have a feeling what you're suggesting would make me have to "reinvent the wheel" here, but I'm just as in the dark as I was before I read that comment.  

Thanks
0
objectsCommented:
he means don't convert them to chars/strings, instead deal with the bytes directly.
When you convert between a string and byte array data conversion takes place according to (in your case) the default character encoding. This process may not be reversible.
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

trs28Author Commented:
Once again, would it be possible to give me an example?  Or would I just remove the (char) section of the line that I write the file with??  Seriously guys, I wasn't mentioning it earlier to watch myself type!   lol   Thanks!
0
trs28Author Commented:
Please make sure you don't get too off track with your (everybody's) suggestions.  I'm sure there are much better ways of doing this, but I need to do this in the manner I described above, so I'm just looking how to account for the problem I'm having.  

0
objectsCommented:
OutputStream outfile = new FileOutputStream(file);
int cnt = 0;
while (cnt < pad.length)
{
     cText[cnt] = (byte)(pText[cnt]^pad[cnt]);
     outfile.write(cText[cnt]);
     cnt++;
 }

similiar to read it back in
0
trs28Author Commented:
I think you've got something going on with that idea....

now my output is ...

Ginè›ravis326


What could be causing the è and › rather than a and T respectively ????   So close!  :)
0
Tommy BraasCommented:
Sorry for not getting back sooner, had meetings...
Use InputStream and OutputStream as your I/O basis. FileInputStream, FileOutputStream.
0
Tommy BraasCommented:
Make sure that you're not casting to 'char' anywhere.
0
trs28Author Commented:
nope - that's not it - i'm not casting to char anywhere, yet the output is still with those two odd characters that i mentioned above.  

any other ideas?  

hell, was thinking about pasting the entire class for you to take a look at, but it is 220 lines or so.   i have a feeling an error like this would have to be "seen" rather than described.  i can always paste it though if need be!   i think it's almost there though!
0
Tommy BraasCommented:
If you post the code here, it is easier for people to refer to the solution. Another solution is to upload it somwhere and post the link here.
0
trs28Author Commented:
// Driver:
//            public class OTP
//            {
//                  public static void main(String[] args)
//                  {
//                         OneTimePadCipher c = new OneTimePadCipher();
//                  }
//
//            }

import java.util.*;
import java.io.*;

public class OneTimePadCipher
{
      private int numberOfBytes;
      private byte[] pText;
      private byte[] cText;
      private byte[] pad;
      
      private int numberOfBits;
      private StringBuffer bitSB;

      public OneTimePadCipher() throws InputMismatchException
      {
            Scanner consoleScan = new Scanner(System.in);
      
            int choice = 0;
            String filename = "";
            
            while (choice != 3)
            {
                  System.out.println("Encryption/Decryption Program");
                  System.out.printf("%11s%n", "1. Encrypt");
                  System.out.printf("%11s%n", "2. Decrypt");
                  System.out.printf("%8s%n", "3. Exit");
                  System.out.println();
                  System.out.printf("%9s", "Choice: ");
                  choice = consoleScan.nextInt();
                  
                  switch (choice)
                  {
                  case 1:
                        System.out.printf("%18s", "File to encrypt: ");
                        filename = consoleScan.next();
                        fetchMessage(filename, true);                                                                  
                        System.out.printf("%38s", "Encrypting ...saved as \"encrypt.txt\"" + "\n");
                        createOneTimePad();
                        transformMessage("encrypt.txt", true);
                        break;
                  case 2:
                        System.out.printf("%18s", "File to decrypt: ");
                        filename = consoleScan.next();
                        fetchMessage(filename, false);
                        System.out.printf("%38s", "Decrypting ...saved as \"decrypt.txt\"" + "\n");
                        createOneTimePad();
                        transformMessage("decrypt.txt", false);
                        break;
                  default:
                        System.out.println();
                        System.out.println("(program terminated)");
                        System.exit(0);
                  }
                  System.out.println();
            }
      }
      
      public void fetchMessage(String file, boolean encrypt)
      {
            FileInputStream fs = null;
            InputStreamReader isr = null;
            BufferedReader fileBR = null;
            int posindex = 0;
            int brValue = 0;
            
            try{
                  fs = new FileInputStream(file);
                  isr = new InputStreamReader(fs);
                  fileBR = new BufferedReader(isr);
                  numberOfBytes = fs.available();
            }catch(FileNotFoundException e){
                  System.out.println(" \"" + file + "\" not found.  Please try again.");
                  System.out.println();
                  new OneTimePadCipher();
            }catch(IOException e){
                  System.out.println(e.getLocalizedMessage());
            }
            
            if (encrypt)
            {
                  pText = new byte[numberOfBytes];
                  posindex = 0;
                  try{
                        brValue = fileBR.read();
                        while (brValue != -1)
                        {
                              pText[posindex++] = (byte)brValue;
                              brValue = fileBR.read();
                        }
                  }catch (IOException e){}
            }
            else
            {
                  cText = new byte[numberOfBytes];
                  posindex = 0;
                  try{
                        brValue = fileBR.read();
                        while (brValue != -1)
                        {
                              cText[posindex++] = (byte)brValue;
                              brValue = fileBR.read();
                        }
                  }catch (IOException e){}
            }
            
            numberOfBits = numberOfBytes * 8;
            bitSB = new StringBuffer(numberOfBits);
            
            try{
                  fs.close();
            }
            catch(IOException e){}
      }
      
      public void createOneTimePad()
      {
            String bitstring = "";
            int counter = 0;      //counter to increment an array seperately within a for loop
            
            generateBits(numberOfBits, bitSB);
            pad = new byte[numberOfBytes];
            for (int i=0; i<bitSB.length(); i+=8)  //cycles 8 bits at a time
            {
                  bitstring = bitSB.substring(i, i+8);
                  pad[counter++] = (byte)Integer.parseInt(twoscomp(bitstring));
            }
      }
      
      private void transformMessage(String file, boolean encrypt)
      {
            FileOutputStream os = null;
            try
            {
                  os = new FileOutputStream(file);
            }
            catch (FileNotFoundException e)
                  {
                        System.out.println(e.getMessage());
                  }            
            
            int cnt = 0;
            try{
                  if (encrypt)
                  {
                        cText = new byte[pText.length];
                        while (cnt < pad.length)
                        {
                              cText[cnt] = (byte)(pText[cnt]^pad[cnt]);
                              os.write(cText[cnt]);
                              cnt++;
                        }
                        cnt = 0;
                  }
                  else
                  {
                        pText = new byte[cText.length];
                        while (cnt < pad.length)
                        {
                              pText[cnt] = (byte)(cText[cnt]^pad[cnt]);
                              os.write(pText[cnt]);
                              cnt++;
                        }
                        cnt = 0;
                  }
            }catch(IOException e){}
            
            try{
                  os.close();
            }catch(IOException e){}
            
      }
      
      private String twoscomp(String s)
      {
            char[] ones = s.toCharArray();
            
            for (int i=0; i<ones.length; i++)
            {
                  if (ones[i] == '0')
                        ones[i] = '1';
                  else if (ones[i] == '1')
                        ones[i] = '0';
            }
            
            int backcount = ones.length-1;      
  twos:      while (backcount >= 0)
            {
                  if (ones[backcount] == '1')
                        ones[backcount] = '0';
                  else if (ones[backcount] == '0')
                  {
                        ones[backcount] = '1';
                        break twos;
                  }
                  backcount--;
            }

            return new String(ones);
    }
      
      private void generateBits(int n, StringBuffer rb)
      {
        boolean b[] = new boolean[11];

        b[10] = false; b[9] = true;  b[8] = true;  b[7] = false;
        b[6] = true;   b[5] = false; b[4] = false; b[3] = false;
        b[2] = false;  b[1] = true;  b[0] = false;

        for (int i=0; i<n; i++)
        {
            boolean bit = b[8] ^ b[10];
            b[10] = b[9]; b[9] = b[8]; b[8] = b[7];
            b[7] = b[6];  b[6] = b[5]; b[5]  = b[4];
            b[4] = b[3];  b[3] = b[2]; b[2] = b[1];
            b[1] = b[0]; b[0] = bit;

            if (bit) rb.append("1");
            else     rb.append("0");
        }
     }
}
0
objectsCommented:
>                fileBR = new BufferedReader(isr);

don't use a Reader

where you are using fileBR to read, instead use fs.
eg.

brValue = fs.read();
0
trs28Author Commented:
You guys are great!
0
Tommy BraasCommented:
;-D
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.