Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 10 of 10

Thread: Incomprehensible bug

  1. #1
    Member
    Join Date
    Jul 2013
    Posts
    47
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Question Incomprehensible bug

    I am really lost on this one.

    I am creating (just for my own practice and because it's kind of cool) a program to encrypt a string according to a very basic algorithm I designed. That part works fine, but of course it needs a decoder.

    I decided to include an access code verification system that will cause the program not to run without a valid access code - again, just because.

    But the debugging output I am getting from this program is insane. Because it's over 400 lines long, I will try to post the least amount of code I can.

    First, here is the pertinent part of main() which executes the decoder if the command line arg is -d:

    else if(args[0].equals("-d")) {
              //Instantiate Decoder object, then run its decode() method.
              System.out.println("main() is instantiating a Decoder.");
              Decoder dec = new Decoder();
              System.out.println("main() is calling dec.decode().");
              dec.decode();
          }
        }
    }

    So all that does, minus comment and debugging prints, is create a Decoder, then run its primary method. Simple so far, yeah?

    Here is the Decoder's constructor:

    class Decoder {
     
        private Scanner scanner;
        private StringBuilder acSB, encSB;
        private String ls;
        private File inf;
        private String decode_this, accessCode;
     
        public Decoder() {
     
            try {
     
                  //File to be encoded must be called "enc.txt" and be in the
                  //INPUT folder.
     
                  inf = new File("C:/StringEncoder/INPUT/enc.txt");
                  scanner = new Scanner(inf);
                  acSB = new StringBuilder((int) inf.length());
                  encSB = new StringBuilder((int) inf.length());
                  ls = System.getProperty("line.separator");
              } catch(FileNotFoundException ex) {
                  System.err.println("ERROR:"
                          + " File to be decoded must be called"
                          + " \"enc.txt\" and must be placed in"
                          + " the INPUT folder.");
                  System.err.println("\n\n" + ex);
                  System.exit(1);
              }
     
            try {
                //First line is access code, so transfer that
                //to acSB.
                acSB.append(scanner.nextLine() + ls);
                //Debugging println()'s.
                System.out.println("acSB toString():");
                System.out.println(acSB.toString());
     
                //Send the rest of the file into encSB.
                while(scanner.hasNextLine()) {
                    encSB.append(scanner.nextLine()+ ls);
                }
            } finally {
     
                //Close scanner up.
                scanner.close();
     
            }
     
            //Deconstructing StringBuilders into Strings.
     
            System.out.println("Constructor sets accessCode:");
            accessCode = acSB.toString();
            System.out.println(accessCode);
            decode_this = encSB.toString();
            System.out.println("Constructor printing accessCode:");
            System.out.println(accessCode);
     
     
     
        }

    So basically, it looks to the input file (which obviously must be in a certain place and have a certain name), scans the first line (which must be the access code) into acSB, scans the rest (which will be the encoded message) into encSB, and closes the scanner. Then it deconstructs the StringBuilders into Strings, prints them for debugging, and it's done!

    Now at NO point yet has there been anything that should call the decode() method. Here is that method:

    public void decode() {
     
            //verifyAccess() is a method to make sure that the access code is
            //a valid one.
            System.out.println("decode() is executing.");
            if(!verifyAccess()) {
                //These println() statements will not display if called
                //from System.out.
                System.err.println("That stupid thing is running.");
                System.err.println("ERROR: Bad access code in file.");
                System.err.println("That stupid thing ran.");
                System.exit(1);
            }
     
        }

    Of course it's incomplete, but given a false return value from verifyAccess(), it doesn't need any more code yet, because it should shut the program down.

    Now, so far, everything looks peachy. But then we look at the output this insanity generates when run with the code so far:

    run:
    main() is instantiating a Decoder.
    acSB toString():
    ZYRSQQSKCYFWNXTZWCJP

    Constructor sets accessCode:
    ZYRSQQSKCYFWNXTZWCJP
    That stupid thing is running.

    ERROR: Bad access code in file.
    Constructor printing accessCode:
    That stupid thing ran.
    ZYRSQQSKCYFWNXTZWCJP

    main() is calling dec.decode().
    decode() is executing.
    verifyAccess() executes.
    false
    Java Result: 1
    BUILD SUCCESSFUL (total time: 0 seconds)
    So as you can see, the System.err.println() calls within the if() statement inside of decode() are being called in the middle of the constructor, which has no calls to decode()! PLUS the debugging statement that indicates that decode() has been called never shows up when that is going on.

    Additionally, if you put those statements inside that culprit if() statement as System.out.println()'s, they will not display. Only error output. But there is no reason that thing should be executing at all. That if() statement is the responsibility of the decode() method, and nothing in the constructor is calling decode(), so there is no way anything of that if() statement should be executing.

    Obviously, I am missing something big. Usually I can figure out where the bug is with enough println()'s and following the trail of execution a few times, but this totally baffles me. Unless there is something I really don't know about scanners or standard error, or maybe file I/O, this pattern of execution seems like it should not be possible.

    I thank anyone in advance for any advice.

    -summit45


  2. #2
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,320
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Incomprehensible bug

    Can't tell on quick glance - I'd recommend posting your code as an SSCCE. Would also recommend cleaning all class files and recompile to make sure an earlier version of your code is not being ran.

  3. #3
    Member
    Join Date
    Jul 2013
    Posts
    47
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Incomprehensible bug

    SSCCE version (still requires -d command line arg just in case that's somehow part of the problem):

    import java.io.IOException;
    import java.io.File;
    import java.io.FileWriter;
    import java.nio.file.*;
    import java.io.FileNotFoundException;
    import java.util.Scanner;
     
    public class StringEncoder {
     
        //In the real program, these are used by main() to read the string to be
        //encrypted so it can feed that to the Encoder object.  I've left them
        //in this SSCCE in case they are part of the problem.
     
        private static Scanner scanner;
        private static StringBuilder sb;
        private static String ls;
        private static File inf;
        private static String str;
     
        public static void main(String[] args) {
     
          if(args[0].equals("-d")) {
              //Instantiate Decoder object, then run its decode() method.
              System.out.println("main() is instantiating a Decoder.");
              Decoder dec = new Decoder();
              System.out.println("main() is calling dec.decode().");
              dec.decode();
          }
        }
    }
     
    class Decoder {
     
        private Scanner scanner;
        private StringBuilder acSB, encSB;
        private String ls;
        private File inf;
        private String decode_this, accessCode;
     
        public Decoder() {
     
            try {
     
                  //File to be encoded must be called "enc.txt" and be in the
                  //INPUT folder.
     
                  inf = new File("C:/StringEncoder/INPUT/enc.txt");
                  scanner = new Scanner(inf);
                  acSB = new StringBuilder((int) inf.length());
                  encSB = new StringBuilder((int) inf.length());
                  ls = System.getProperty("line.separator");
              } catch(FileNotFoundException ex) {
                  System.err.println("ERROR:"
                          + " File to be decoded must be called"
                          + " \"enc.txt\" and must be placed in"
                          + " the INPUT folder.");
                  System.err.println("\n\n" + ex);
                  System.exit(1);
              }
     
            try {
                //First line is access code, so transfer that
                //to acSB.
                acSB.append(scanner.nextLine() + ls);
                //Debugging println()'s.
                System.out.println("acSB toString():");
                System.out.println(acSB.toString());
     
                //Send the rest of the file into encSB.
                while(scanner.hasNextLine()) {
                    encSB.append(scanner.nextLine()+ ls);
                }
            } finally {
     
                //Close scanner; debugging prints.
                scanner.close();
     
            }
     
            //Deconstructing StringBuilders into Strings.
     
            System.out.println("Constructor sets accessCode:");
            accessCode = acSB.toString();
            System.out.println(accessCode);
            decode_this = encSB.toString();
            System.out.println("Constructor printing accessCode:");
            System.out.println(accessCode);
     
     
     
        }
     
        public void decode() {
     
            //verifyAccess() is a method to make sure that the access code is
            //a valid one.
            System.out.println("decode() is executing.");
            if(!verifyAccess()) {
                //These println() statements will not display if called
                //from System.out.
                System.err.println("That stupid thing is running.");
                System.err.println("ERROR: Bad access code in file.");
                System.err.println("That stupid thing ran.");
                System.exit(1);
            }
     
        }
     
        private boolean verifyAccess() {
            System.out.println("verifyAccess() executes.");
     
            //Transform accessCode to a char array,
            //create a char array containing the valid
            //characters for each key position,
            //and create one more char array
            //to hold the pertinent values.
     
            char[] charAr = accessCode.toCharArray();
            char[] acList = new char[5];
            char[] acAr = new char[5];
            boolean retVal = false;
     
            acAr[0] = charAr[1];
            acAr[1] = charAr[5];
            acAr[2] = charAr[9];
            acAr[3] = charAr[11];
            acAr[4] = charAr[16];
     
            acList[0] = 'Q';
            acList[1] = 'Y';
            acList[2] = 'J';
            acList[3] = 'W';
     
            //Check each pertinent char from the access code
            //against the acceptable values.
     
            //If even one does not match, return a false
            //value.
     
            for(int i = 0; i < acAr.length; i++) {
     
                for(int j = 0; j < acList.length; j++) {
                    if(acAr[i] == acList[j]) {
                        break;
                    }
     
                    else if(j < acList.length + 1) {
                        continue;
                    }
     
                    else {
                        return retVal;
                    }
                }
     
                if(i == acAr.length) {
                    retVal = true;
                }
            }
     
            System.out.println(retVal);
            return retVal;
        }
    }

    The verifyAccess() method is bugged and returns false even with a valid access code, but that seems like it's probably not so hard to correct (though just at a quick look I'm not entirely sure what's wrong with it). The main annoyance now is the insanity this thing produces for output.

    To run this, you must have a folder C:\StringEncoder\INPUT in which there is a file with input data called enc.txt. Here is a sample file, just the one I've been using (the space before "fkciff" in the end should not be there; it's not present in my file, the forums are doing it):

    VJCGGWRUAJVWMZOFJVGQ

    tlavaasoyqljjjcqciopiqilgqlshosvwrqfbzwniokhftoyor nhbjyuzlfhanjepzpbpmsjtiuccghpgzprnrysjyphptcoxhsl jioldwevunrdbyeshhrxwhmxmpzkmadsifflcrqiklktbqstqj jtfhtftelvwqmnjjgcrupsxniyacjigoufitglipafaawdbeks hxsnakviivhrntratupttlhecmmrrbcorsvmtsdorippfcasnc lryuenjhocrvpdgspzdgnhdmvipgplifktmvkkueupwndsnouc qudxlvrbqfebzjphqcxftilzqeluqhcguzzuebfebssnehpynk phpnczwhnigptwqkqcdjxqemjsxmcwvoxkpgzkwbguxbudqgmb shnnxqclhewwkqafwpzaqijdnanfqgwbfphhbbmqgqilzlhgdy nycdrqpuqykxvvctdfvcdkgevzgjyhjawugezkpuvaneaogiht eotrntopdjwfbcratopiqrsflfwslhyjgwoofuilbxdukoflkg ptcvolitpjychrbfsbktstabdxlacvnmipbgluslzmlheprcya tpisibfvsrgcwxbekocwqhwooivvfushpuxqhikobwubdlisps gmkwykxcmeldecttbwocdndnyynvghfadprkfkuwqwbtpccvcl pvhxxmvolmghpukyqbndxgtgjgqdjwdiujdmxdbnvfghcrjeyq fkciff
    The first line is the access code, the rest is the encrypted string. Of course that's irrelevant since the decrypting code isn't written yet, and actually even the access code is pretty irrelevant for the purposes of the bug I'm getting - but you have to have the file nonetheless.

    -summit45

    --- Update ---

    You've got to be kidding me... well the SSCCE actually WORKS. Okay then, here is the whole program (sorry, folks):

    import java.io.IOException;
    import java.io.File;
    import java.io.FileWriter;
    import java.nio.file.*;
    import java.io.FileNotFoundException;
    import java.util.Scanner;
     
    public class StringEncoder {
     
        //Declaring all things which will be used by main()
        //to retrieve file data for feeding to the other methods.
     
        private static Scanner scanner;
        private static StringBuilder sb;
        private static String ls;
        private static File inf;
        private static String str;
     
        public static void main(String[] args) {
     
            //Print an error message if the user has input no
            //usage arguments.
     
          if(args.length == 0) {
              System.err.println("No string entered.  Terminating program.");
              System.exit(0);
          }
     
          //User need only type -e at the command line to encode
          //a file.  File identification is handled by program
          //convention.
     
          if(args[0].equals("-e")) {
              try {
     
                  //File to be encoded must be called "enc.txt" and be in the
                  //INPUT folder.
     
                  inf = new File("C:/StringEncoder/INPUT/enc.txt");
                  scanner = new Scanner(inf);
                  sb = new StringBuilder((int) inf.length());
                  ls = System.getProperty("line.separator");
              } catch(FileNotFoundException ex) {
                  System.err.println("ERROR:"
                          + " File to be encoded must be called"
                          + " \"enc.txt\" and must be placed in"
                          + " the INPUT folder.");
                  System.err.println("\n\n" + ex);
                  System.exit(1);
              }
     
              try {
     
                  //Read file data into a StringBuilder object
                  //and transfer to String for feeding to
                  //encoding method.
     
                  while(scanner.hasNextLine()) {
                      sb.append(scanner.nextLine() + ls);
                  }
     
                      str = sb.toString();
              } finally {
                  scanner.close();
              }
     
     
              //Declare and activate Encoder object.
     
              Encoder encoder = new Encoder(str);
     
          encoder.encode();
        }
     
          else if(args[0].equals("-d")) {
              //Instantiate Decoder object, then run its decode() method.
              System.out.println("main() is instantiating a Decoder.");
              Decoder dec = new Decoder();
              System.out.println("main() is calling dec.decode().");
              dec.decode();
          }
        }
    }
     
     
     
     
    class Encoder {
     
        //FileWriter object out will be used to write
        //the encoded output file.
     
        private static String ls = System.getProperty("line.separator");
        private String encode_this;
        private FileWriter out = null;
     
        public Encoder(String s) { 
     
        //Following two methods are used to streamline the
        //input.
     
           encode_this = s.toLowerCase();
           encode_this = sterilize(encode_this);
     
        }
     
        public void encode() {
     
     
            int monitor = encode_this.length() * 13;
            //monitor var is used to store the length of the original
            //string, otherwise the for() loop will run forever.
            //Multiply by 13 because garbage strings are inserted at every
            //thirteenth letter.
     
            String s;
            String firstHalf; 
            String secondHalf;
     
     
     
            for(int i = 0; i < monitor; i+=14) {
     
                s = randomizer(13);
                firstHalf = encode_this.substring(0, i);
                secondHalf = encode_this.substring(i);
                encode_this = firstHalf + s + secondHalf;
     
     
            }
     
            encode_this = "sv" + encode_this + "tgj";
     
     
            for(int j = 0; j < Math.round(Math.random() * 11); j++) {
     
                encode_this = randomizer(10) + encode_this + randomizer(10);
     
            }
     
     
            Path outf = Paths.get("C:/StringEncoder/ENCODED/enc.txt");
            try {
                Files.createFile(outf);
            } catch(FileAlreadyExistsException ex) {
                System.err.println("ERROR: enc.txt file already exists."
                        + "  Delete and re-run program to continue.");
                System.exit(1);
            } catch(IOException ex) {
                System.err.println("ERROR: IOException on enc.txt creation.");
                System.err.println(ex);
                System.exit(1);
            }
     
     
            try {
                out = new FileWriter(new File("C:/StringEncoder/ENCODED/enc.txt"));
     
            } catch(FileNotFoundException ex) {
                System.err.println("ERROR: Failed to create enc.txt.");
                System.err.println(ex);
                System.exit(1);
            } catch(IOException ex) {
                System.err.println("ERROR: IOException on writer construction.");
                System.err.println(ex);
                System.exit(1);
            }
     
           try {
               out.write(createAccessCode());
               out.write(ls);
               out.write(ls);
           } catch(IOException ex) {
               System.err.println("ERROR: IOException on enc.txt write operation.");
               ex.printStackTrace();
               System.exit(1);
           }
     
           encode_this = sterilize(encode_this);
     
            try {
     
               out.write(encode_this);
     
               out.close();
           } catch(IOException ex) {
               System.err.println("ERROR: IOException on enc.txt write operation.");
               ex.printStackTrace();
               System.exit(1);
           }
     
        }
     
        private String randomizer(int It) {
            long[] array = new long[It];
     
            for(int i = 0; i < It; i++) {
     
                array[i] = 97 + (Math.round(Math.random() * 25));
            }
     
             char[] charAr = new char[array.length];
     
            for(int i = 0; i < charAr.length; i++) {
                charAr[i] = (char) array[i];
            }
     
            String s = "";
     
            for(int i = 0; i < charAr.length; i++) {
     
                s += charAr[i];
            }
     
            for(int i = 0; i < charAr.length - 1; i++) {
                if(charAr[i] == 's' && charAr[i+1] == 'v') {
                    char[] c;
                    String sa;
                    sa = randomizer(1);
                    c = sa.toCharArray();
                    charAr[i] = c[0];
     
                    }
            }
            return s;
        }
     
        private String sterilize(String s) {
     
            int[] sterInt1 = new int[97];
            int[] sterInt2 = new int[4];
     
            for(int i = 0; i < 96; i++) {
                sterInt1[i] = i;
            }
     
            sterInt1[96] = 96;
     
            for(int i = 0; i < 4; i++) {
                int h = i + 123 ;
                sterInt2[i] = h;
            }
     
            char[] sterAr = s.toCharArray();
            int[] intAr = new int[sterAr.length];
     
            for(int i = 0; i < sterAr.length; i++) {
                intAr[i] = (int) sterAr[i];
     
            }
     
            int[] finInt = new int[intAr.length];
            int lastPlace = 0;
            int finIntArPos = 0;
     
            for(int i = 0; i < intAr.length; i++) {
     
                for(int j = 0; j < sterInt1.length; j++) {
     
                    if(j == sterInt1.length - 1 && intAr[i] != sterInt1[j]) {
                        finInt[finIntArPos] = intAr[i];
                        finIntArPos++;
                        break;
                    }
     
                    if(intAr[i] != sterInt1[j]) {
                        continue;
                    }
                    else if(intAr[i] == sterInt1[j]) {
                        break;
                    }
     
            }
     
                lastPlace = i;
            }
     
     
            for(int i = lastPlace; i < intAr.length; i++) {
     
                for(int j = 0; j < sterInt2.length; j++) {
                    if(j == sterInt2.length - 1 && intAr[i] != sterInt2[j]) {
                        finInt[finIntArPos] = intAr[i];
                        finIntArPos++;
                        break;
                    }
     
                    if(intAr[i] != sterInt2[j]) {
                        continue;
                    }
     
                    else if(intAr[i] == sterInt2[j]) {
                        break;
                    }
                }
            }
     
     
            char[] finChar = new char[finInt.length];
     
            for(int i = 0; i < finInt.length; i++) {
                finChar[i] = (char) finInt[i];
            }
            StringBuilder sb = new StringBuilder(finChar.length);
            sb.append(finChar);
            String retStr = sb.toString();
            System.out.println(retStr);
            return retStr;
        }
     
        private String createAccessCode() {
     
            String str = randomizer(20);
            char[] charAr = str.toCharArray();
     
            char[] accessList = new char[4];
     
            accessList[0] = 'Q';
            accessList[1] = 'Y';
            accessList[2] = 'J';
            accessList[3] = 'W';
     
            charAr[1] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[5] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[9] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[11] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[16] = accessList[(int) Math.round(Math.random() * 3.5)];
     
            StringBuilder sb = new StringBuilder(charAr.length);
            sb.append(charAr);
            String retStr = sb.toString();
            retStr = retStr.toUpperCase();
            System.out.println(retStr);
            return retStr;
        }
    }
     
    class Decoder {
     
        private Scanner scanner;
        private StringBuilder acSB, encSB;
        private String ls;
        private File inf;
        private String decode_this, accessCode;
     
        public Decoder() {
     
            try {
     
                  //File to be encoded must be called "enc.txt" and be in the
                  //INPUT folder.
     
                  inf = new File("C:/StringEncoder/INPUT/enc.txt");
                  scanner = new Scanner(inf);
                  acSB = new StringBuilder((int) inf.length());
                  encSB = new StringBuilder((int) inf.length());
                  ls = System.getProperty("line.separator");
              } catch(FileNotFoundException ex) {
                  System.err.println("ERROR:"
                          + " File to be decoded must be called"
                          + " \"enc.txt\" and must be placed in"
                          + " the INPUT folder.");
                  System.err.println("\n\n" + ex);
                  System.exit(1);
              }
     
            try {
                //First line is access code, so transfer that
                //to acSB.
                acSB.append(scanner.nextLine() + ls);
                //Debugging println()'s.
                System.out.println("acSB toString():");
                System.out.println(acSB.toString());
     
                //Send the rest of the file into encSB.
                while(scanner.hasNextLine()) {
                    encSB.append(scanner.nextLine()+ ls);
                }
            } finally {
     
                //Close scanner; debugging prints.
                scanner.close();
     
            }
     
            //Deconstructing StringBuilders into Strings.
     
            System.out.println("Constructor sets accessCode:");
            accessCode = acSB.toString();
            System.out.println(accessCode);
            decode_this = encSB.toString();
            System.out.println("Constructor printing accessCode:");
            System.out.println(accessCode);
     
     
     
        }
     
        public void decode() {
     
            //verifyAccess() is a method to make sure that the access code is
            //a valid one.
            System.out.println("decode() is executing.");
            if(!verifyAccess()) {
                //These println() statements will not display if called
                //from System.out.
                System.err.println("That stupid thing is running.");
                System.err.println("ERROR: Bad access code in file.");
                System.err.println("That stupid thing ran.");
                System.exit(1);
            }
     
        }
     
        private boolean verifyAccess() {
            System.out.println("verifyAccess() executes.");
     
            //Transform accessCode to a char array,
            //create a char array containing the valid
            //characters for each key position,
            //and create one more char array
            //to hold the pertinent values.
     
            char[] charAr = accessCode.toCharArray();
            char[] acList = new char[5];
            char[] acAr = new char[5];
            boolean retVal = false;
     
            acAr[0] = charAr[1];
            acAr[1] = charAr[5];
            acAr[2] = charAr[9];
            acAr[3] = charAr[11];
            acAr[4] = charAr[16];
     
            acList[0] = 'Q';
            acList[1] = 'Y';
            acList[2] = 'J';
            acList[3] = 'W';
     
            //Check each pertinent char from the access code
            //against the acceptable values.
     
            //If even one does not match, return a false
            //value.
     
            for(int i = 0; i < acAr.length; i++) {
     
                for(int j = 0; j < acList.length; j++) {
                    if(acAr[i] == acList[j]) {
                        break;
                    }
     
                    else if(j < acList.length + 1) {
                        continue;
                    }
     
                    else {
                        return retVal;
                    }
                }
     
                if(i == acAr.length) {
                    retVal = true;
                }
            }
     
            System.out.println(retVal);
            return retVal;
        }
    }

    -summit45

    --- Update ---

    You've got to be kidding me... well the SSCCE actually WORKS. Okay then, here is the whole program (sorry, folks):

    import java.io.IOException;
    import java.io.File;
    import java.io.FileWriter;
    import java.nio.file.*;
    import java.io.FileNotFoundException;
    import java.util.Scanner;
     
    public class StringEncoder {
     
        //Declaring all things which will be used by main()
        //to retrieve file data for feeding to the other methods.
     
        private static Scanner scanner;
        private static StringBuilder sb;
        private static String ls;
        private static File inf;
        private static String str;
     
        public static void main(String[] args) {
     
            //Print an error message if the user has input no
            //usage arguments.
     
          if(args.length == 0) {
              System.err.println("No string entered.  Terminating program.");
              System.exit(0);
          }
     
          //User need only type -e at the command line to encode
          //a file.  File identification is handled by program
          //convention.
     
          if(args[0].equals("-e")) {
              try {
     
                  //File to be encoded must be called "enc.txt" and be in the
                  //INPUT folder.
     
                  inf = new File("C:/StringEncoder/INPUT/enc.txt");
                  scanner = new Scanner(inf);
                  sb = new StringBuilder((int) inf.length());
                  ls = System.getProperty("line.separator");
              } catch(FileNotFoundException ex) {
                  System.err.println("ERROR:"
                          + " File to be encoded must be called"
                          + " \"enc.txt\" and must be placed in"
                          + " the INPUT folder.");
                  System.err.println("\n\n" + ex);
                  System.exit(1);
              }
     
              try {
     
                  //Read file data into a StringBuilder object
                  //and transfer to String for feeding to
                  //encoding method.
     
                  while(scanner.hasNextLine()) {
                      sb.append(scanner.nextLine() + ls);
                  }
     
                      str = sb.toString();
              } finally {
                  scanner.close();
              }
     
     
              //Declare and activate Encoder object.
     
              Encoder encoder = new Encoder(str);
     
          encoder.encode();
        }
     
          else if(args[0].equals("-d")) {
              //Instantiate Decoder object, then run its decode() method.
              System.out.println("main() is instantiating a Decoder.");
              Decoder dec = new Decoder();
              System.out.println("main() is calling dec.decode().");
              dec.decode();
          }
        }
    }
     
     
     
     
    class Encoder {
     
        //FileWriter object out will be used to write
        //the encoded output file.
     
        private static String ls = System.getProperty("line.separator");
        private String encode_this;
        private FileWriter out = null;
     
        public Encoder(String s) { 
     
        //Following two methods are used to streamline the
        //input.
     
           encode_this = s.toLowerCase();
           encode_this = sterilize(encode_this);
     
        }
     
        public void encode() {
     
     
            int monitor = encode_this.length() * 13;
            //monitor var is used to store the length of the original
            //string, otherwise the for() loop will run forever.
            //Multiply by 13 because garbage strings are inserted at every
            //thirteenth letter.
     
            String s;
            String firstHalf; 
            String secondHalf;
     
     
     
            for(int i = 0; i < monitor; i+=14) {
     
                s = randomizer(13);
                firstHalf = encode_this.substring(0, i);
                secondHalf = encode_this.substring(i);
                encode_this = firstHalf + s + secondHalf;
     
     
            }
     
            encode_this = "sv" + encode_this + "tgj";
     
     
            for(int j = 0; j < Math.round(Math.random() * 11); j++) {
     
                encode_this = randomizer(10) + encode_this + randomizer(10);
     
            }
     
     
            Path outf = Paths.get("C:/StringEncoder/ENCODED/enc.txt");
            try {
                Files.createFile(outf);
            } catch(FileAlreadyExistsException ex) {
                System.err.println("ERROR: enc.txt file already exists."
                        + "  Delete and re-run program to continue.");
                System.exit(1);
            } catch(IOException ex) {
                System.err.println("ERROR: IOException on enc.txt creation.");
                System.err.println(ex);
                System.exit(1);
            }
     
     
            try {
                out = new FileWriter(new File("C:/StringEncoder/ENCODED/enc.txt"));
     
            } catch(FileNotFoundException ex) {
                System.err.println("ERROR: Failed to create enc.txt.");
                System.err.println(ex);
                System.exit(1);
            } catch(IOException ex) {
                System.err.println("ERROR: IOException on writer construction.");
                System.err.println(ex);
                System.exit(1);
            }
     
           try {
               out.write(createAccessCode());
               out.write(ls);
               out.write(ls);
           } catch(IOException ex) {
               System.err.println("ERROR: IOException on enc.txt write operation.");
               ex.printStackTrace();
               System.exit(1);
           }
     
           encode_this = sterilize(encode_this);
     
            try {
     
               out.write(encode_this);
     
               out.close();
           } catch(IOException ex) {
               System.err.println("ERROR: IOException on enc.txt write operation.");
               ex.printStackTrace();
               System.exit(1);
           }
     
        }
     
        private String randomizer(int It) {
            long[] array = new long[It];
     
            for(int i = 0; i < It; i++) {
     
                array[i] = 97 + (Math.round(Math.random() * 25));
            }
     
             char[] charAr = new char[array.length];
     
            for(int i = 0; i < charAr.length; i++) {
                charAr[i] = (char) array[i];
            }
     
            String s = "";
     
            for(int i = 0; i < charAr.length; i++) {
     
                s += charAr[i];
            }
     
            for(int i = 0; i < charAr.length - 1; i++) {
                if(charAr[i] == 's' && charAr[i+1] == 'v') {
                    char[] c;
                    String sa;
                    sa = randomizer(1);
                    c = sa.toCharArray();
                    charAr[i] = c[0];
     
                    }
            }
            return s;
        }
     
        private String sterilize(String s) {
     
            int[] sterInt1 = new int[97];
            int[] sterInt2 = new int[4];
     
            for(int i = 0; i < 96; i++) {
                sterInt1[i] = i;
            }
     
            sterInt1[96] = 96;
     
            for(int i = 0; i < 4; i++) {
                int h = i + 123 ;
                sterInt2[i] = h;
            }
     
            char[] sterAr = s.toCharArray();
            int[] intAr = new int[sterAr.length];
     
            for(int i = 0; i < sterAr.length; i++) {
                intAr[i] = (int) sterAr[i];
     
            }
     
            int[] finInt = new int[intAr.length];
            int lastPlace = 0;
            int finIntArPos = 0;
     
            for(int i = 0; i < intAr.length; i++) {
     
                for(int j = 0; j < sterInt1.length; j++) {
     
                    if(j == sterInt1.length - 1 && intAr[i] != sterInt1[j]) {
                        finInt[finIntArPos] = intAr[i];
                        finIntArPos++;
                        break;
                    }
     
                    if(intAr[i] != sterInt1[j]) {
                        continue;
                    }
                    else if(intAr[i] == sterInt1[j]) {
                        break;
                    }
     
            }
     
                lastPlace = i;
            }
     
     
            for(int i = lastPlace; i < intAr.length; i++) {
     
                for(int j = 0; j < sterInt2.length; j++) {
                    if(j == sterInt2.length - 1 && intAr[i] != sterInt2[j]) {
                        finInt[finIntArPos] = intAr[i];
                        finIntArPos++;
                        break;
                    }
     
                    if(intAr[i] != sterInt2[j]) {
                        continue;
                    }
     
                    else if(intAr[i] == sterInt2[j]) {
                        break;
                    }
                }
            }
     
     
            char[] finChar = new char[finInt.length];
     
            for(int i = 0; i < finInt.length; i++) {
                finChar[i] = (char) finInt[i];
            }
            StringBuilder sb = new StringBuilder(finChar.length);
            sb.append(finChar);
            String retStr = sb.toString();
            System.out.println(retStr);
            return retStr;
        }
     
        private String createAccessCode() {
     
            String str = randomizer(20);
            char[] charAr = str.toCharArray();
     
            char[] accessList = new char[4];
     
            accessList[0] = 'Q';
            accessList[1] = 'Y';
            accessList[2] = 'J';
            accessList[3] = 'W';
     
            charAr[1] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[5] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[9] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[11] = accessList[(int) Math.round(Math.random() * 3.5)];
            charAr[16] = accessList[(int) Math.round(Math.random() * 3.5)];
     
            StringBuilder sb = new StringBuilder(charAr.length);
            sb.append(charAr);
            String retStr = sb.toString();
            retStr = retStr.toUpperCase();
            System.out.println(retStr);
            return retStr;
        }
    }
     
    class Decoder {
     
        private Scanner scanner;
        private StringBuilder acSB, encSB;
        private String ls;
        private File inf;
        private String decode_this, accessCode;
     
        public Decoder() {
     
            try {
     
                  //File to be encoded must be called "enc.txt" and be in the
                  //INPUT folder.
     
                  inf = new File("C:/StringEncoder/INPUT/enc.txt");
                  scanner = new Scanner(inf);
                  acSB = new StringBuilder((int) inf.length());
                  encSB = new StringBuilder((int) inf.length());
                  ls = System.getProperty("line.separator");
              } catch(FileNotFoundException ex) {
                  System.err.println("ERROR:"
                          + " File to be decoded must be called"
                          + " \"enc.txt\" and must be placed in"
                          + " the INPUT folder.");
                  System.err.println("\n\n" + ex);
                  System.exit(1);
              }
     
            try {
                //First line is access code, so transfer that
                //to acSB.
                acSB.append(scanner.nextLine() + ls);
                //Debugging println()'s.
                System.out.println("acSB toString():");
                System.out.println(acSB.toString());
     
                //Send the rest of the file into encSB.
                while(scanner.hasNextLine()) {
                    encSB.append(scanner.nextLine()+ ls);
                }
            } finally {
     
                //Close scanner; debugging prints.
                scanner.close();
     
            }
     
            //Deconstructing StringBuilders into Strings.
     
            System.out.println("Constructor sets accessCode:");
            accessCode = acSB.toString();
            System.out.println(accessCode);
            decode_this = encSB.toString();
            System.out.println("Constructor printing accessCode:");
            System.out.println(accessCode);
     
     
     
        }
     
        public void decode() {
     
            //verifyAccess() is a method to make sure that the access code is
            //a valid one.
            System.out.println("decode() is executing.");
            if(!verifyAccess()) {
                //These println() statements will not display if called
                //from System.out.
                System.err.println("That stupid thing is running.");
                System.err.println("ERROR: Bad access code in file.");
                System.err.println("That stupid thing ran.");
                System.exit(1);
            }
     
        }
     
        private boolean verifyAccess() {
            System.out.println("verifyAccess() executes.");
     
            //Transform accessCode to a char array,
            //create a char array containing the valid
            //characters for each key position,
            //and create one more char array
            //to hold the pertinent values.
     
            char[] charAr = accessCode.toCharArray();
            char[] acList = new char[5];
            char[] acAr = new char[5];
            boolean retVal = false;
     
            acAr[0] = charAr[1];
            acAr[1] = charAr[5];
            acAr[2] = charAr[9];
            acAr[3] = charAr[11];
            acAr[4] = charAr[16];
     
            acList[0] = 'Q';
            acList[1] = 'Y';
            acList[2] = 'J';
            acList[3] = 'W';
     
            //Check each pertinent char from the access code
            //against the acceptable values.
     
            //If even one does not match, return a false
            //value.
     
            for(int i = 0; i < acAr.length; i++) {
     
                for(int j = 0; j < acList.length; j++) {
                    if(acAr[i] == acList[j]) {
                        break;
                    }
     
                    else if(j < acList.length + 1) {
                        continue;
                    }
     
                    else {
                        return retVal;
                    }
                }
     
                if(i == acAr.length) {
                    retVal = true;
                }
            }
     
            System.out.println(retVal);
            return retVal;
        }
    }

    -summit45

    --- Update ---

    As a matter of fact, that full version is also working (minus the verifyAccess() bug), when I compiled it with javac from Notepad and put the .java and .class filed in C:\StringEncoder (originally I was working in NetBeans).

    Okay, whatever. I'm just gonna go sit in a corner now. I have no idea why it works in its own folder but spits garbage in NetBeans, but it does.

    -summit45

    --- Update ---

    As a matter of fact, that full version is also working (minus the verifyAccess() bug), when I compiled it with javac from Notepad and put the .java and .class filed in C:\StringEncoder (originally I was working in NetBeans).

    Okay, whatever. I'm just gonna go sit in a corner now. I have no idea why it works in its own folder but spits garbage in NetBeans, but it does.

    -summit45

  4. #4
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,320
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Incomprehensible bug

    Here's the output I get, which seems to me to make sense based upon the code
    main() is instantiating a Decoder.
    acSB toString():
    VJCGGWRUAJVWMZOFJVGQ
     
    Constructor sets accessCode:
    VJCGGWRUAJVWMZOFJVGQ
     
    Constructor printing accessCode:
    VJCGGWRUAJVWMZOFJVGQ
     
    main() is calling dec.decode().
    decode() is executing.
    verifyAccess() executes.
    false
    That stupid thing is running.
    ERROR: Bad access code in file.
    That stupid thing ran.

  5. #5
    Member
    Join Date
    Jul 2013
    Posts
    47
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Incomprehensible bug

    Yeah, it only gives me bad output when I execute it in NetBeans. I have no idea why that would be so. It works even if I execute it from the command line in the NetBeans build folder for this project - but if I run it actually IN NetBeans, garbage output, like I showed before.

    -summit45

  6. #6
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Incomprehensible bug

    Have you tried deleting existing .class files, recompiling the whole thing, and running the result? Sometimes Eclipse gets hung on using old versions of source files that have been changed. I don't have much experience with Netbeans, but perhaps it sometimes has the same problem.

  7. #7
    Member
    Join Date
    Jul 2013
    Posts
    47
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Default Re: Incomprehensible bug

    Quote Originally Posted by GregBrannon View Post
    Have you tried deleting existing .class files, recompiling the whole thing, and running the result? Sometimes Eclipse gets hung on using old versions of source files that have been changed. I don't have much experience with Netbeans, but perhaps it sometimes has the same problem.
    Well I have run the "Build & Clean" option more than once already. Same issue. Even so, there was never a version of the code where decode() was called from the constructor anyway. Could it be a bug in NetBeans of some sort?

    -summit45

  8. #8
    Super Moderator jps's Avatar
    Join Date
    Jul 2012
    Posts
    2,642
    My Mood
    Daring
    Thanks
    90
    Thanked 263 Times in 232 Posts

    Default Re: Incomprehensible bug

    Quote Originally Posted by summit45 View Post
    SSCCE version (still requires -d command line arg just in case that's somehow part of the problem):
     if(args[0].equals("-d")) {
              //Instantiate Decoder object, then run its decode() method.
              System.out.println("main() is instantiating a Decoder.");
              Decoder dec = new Decoder();
              System.out.println("main() is calling dec.decode().");
              dec.decode();
          }
        }
    }
    decode is being called from main, not the constructor

  9. #9
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Incomprehensible bug

    I think I know what's going on, but I'm not sure I can explain it well.

    Have you ever noticed that sometimes the error/stack trace output appears in the middle of the program's normal output? Or after a few lines of it, and then the normal output may continue or be complete? Since you're using the System.err output stream, I think the error message is being output before what appears to be the normal System.out.println() outputs which use the standard output. I don't know how that injection occurs or the priority is set, but the err output stream is getting ahead of standard output, causing the confusion.

    Edit: Said slightly better, the err output stream and the std output stream are run on separate threads, and the err output stream may have a higher priority. Once the error message is sent to the err output stream, the message is output in the middle of the standard output which is already happening, and then the standard output thread completes. Does this happen before the program exits, or are the outputs flushed and completed as part of the program ending? Don't know.

    It's a guess, and I can't prove it on my system, but try changing the System.err messages to use the standard output and see if you get the same results.

  10. The Following User Says Thank You to GregBrannon For This Useful Post:

    copeg (September 3rd, 2013)

  11. #10
    Super Moderator jps's Avatar
    Join Date
    Jul 2012
    Posts
    2,642
    My Mood
    Daring
    Thanks
    90
    Thanked 263 Times in 232 Posts

    Default Re: Incomprehensible bug

    Quote Originally Posted by GregBrannon View Post
    Have you ever noticed that sometimes the error/stack trace output appears in the middle of the program's normal output? Or after a few lines of it, and then the normal output may continue or be complete?....
    That is the cause of the placement of the text, and an example why println is not the best debugger

Similar Threads

  1. Login bug
    By 0w1 in forum Loops & Control Statements
    Replies: 0
    Last Post: July 17th, 2013, 09:28 PM
  2. nullpointerexception bug
    By Jedi khan in forum What's Wrong With My Code?
    Replies: 7
    Last Post: July 11th, 2013, 09:01 AM
  3. What's the bug in this code?
    By r3dApple in forum What's Wrong With My Code?
    Replies: 4
    Last Post: January 11th, 2012, 12:28 AM
  4. KeyListener bug
    By nivangerow in forum AWT / Java Swing
    Replies: 1
    Last Post: September 5th, 2011, 06:10 AM
  5. Apparent bug?
    By 342-173=147 in forum Loops & Control Statements
    Replies: 2
    Last Post: March 4th, 2011, 02:52 PM