CyberArmy University | Open Source Institute | CyberArmy Intelligence & Security | CyberArmy Services & Projects

Desktop Version



    Desktop Version [View] [Reply] [Top]
    Posted by CinC snarkles On 2005-02-15 17:19:31
    his thread is to discuss the development of the desktop version of SNEAK.
     
      Java - HTML Entities Encr/decr - draft 1 [View] [Reply] [Top]
      Posted by Alpha Cpt FantaSy On 2006-01-03 05:04:05
      Please note that all these functions *could* be done using the MonoAlfabCipher class too :)

      - ENCRYPTING -
      String output = "";
      	for (int i=0;i<input.length();i++) {
      		output= output + "&#"+String.valueOf((int) (input.charAt(i)))+";";
      	}
      	return output;
      - EOF -

      - DECRYPTING -
      	int index=0;
      	int index2=0;
      
      	while (index2<input.length()-1) {
      		index=input.indexOf("&#",index)+2;
      		index2=input.indexOf(";",index);
      		
      		String subString = input.substring(index,index2);
      		outputString2=outputString2+(char)(Integer.parseInt(subString));
      	}
      - EOF -
       
        Oh, you've done the HTML encode/decode [View] [Reply] [Top]
        Posted by Beta Cpt SAJChurchey On 2006-02-05 05:33:58
        Take a look at our current code and design, and write the class. Write an accompanying test as well and we'll add it.
         
      Java - RSA Implementation [View] [Reply] [Top]
      Posted by Lt CyberTNT On 2005-03-21 03:08:22
      No javadoc comments / junit tests yet.
      package net.cyberarmy.sneak.algorithm;
      
      import java.beans.IntrospectionException;
      import java.beans.PropertyDescriptor;
      
      import java.math.BigInteger;
      
      
      /**
       *
       *
       * @author Cybertnt
       * @since 21.03.2005
       */
      public class RSA extends Cipher implements DataDependentAlgorithm {
          private BigInteger publicKey;
          private BigInteger privateKey;
          private BigInteger moduloKey;
      
          private String execute(String input, BigInteger key) {
              String[] splitInput = input.split(" ");
              StringBuffer result = new StringBuffer();
      
              for (int i = 0; i < splitInput.length; i++) {
                  result.append(execute(BigInteger.valueOf(Long.parseLong(
                                  splitInput[i])), key, moduloKey));
                  result.append(' ');
              }
      
              return result.toString().trim();
          }
      
          private BigInteger execute(BigInteger input, BigInteger key,
              BigInteger moduloKey) {
              return input.modPow(key, moduloKey);
          }
      
          public String execute(String input) {
              return execute(input, publicKey);
          }
      
          public String reverse(String input) {
              return execute(input, privateKey);
          }
      
          public PropertyDescriptor[] getRequiredProperties() {
              try {
                  return new PropertyDescriptor[] {
                      new PropertyDescriptor("publicKey", RSA.class),
                      new PropertyDescriptor("privateKey", RSA.class),
                      new PropertyDescriptor("moduloKey", RSA.class)
                  };
              } catch (IntrospectionException exc) {
                  exc.printStackTrace();
              }
      
              return null;
          }
      
          /**
           * @return Returns the publicKey.
           */
          public long getPublicKey() {
              return publicKey.longValue();
          }
      
          /**
           * @param publicKey The publicKey to set.
           */
          public void setPublicKey(long publicKey) {
              this.publicKey = BigInteger.valueOf(publicKey);
          }
      
          /**
           * @return Returns the privateKey.
           */
          public long getPrivateKey() {
              return privateKey.longValue();
          }
      
          /**
           * @param privateKey The privateKey to set.
           */
          public void setPrivateKey(long privateKey) {
              this.privateKey = BigInteger.valueOf(privateKey);
          }
      
          /**
           * @return Returns the moduloKey.
           */
          public long getModuloKey() {
              return moduloKey.longValue();
          }
      
          /**
           * @param moduloKey The moduloKey to set.
           */
          public void setModuloKey(long moduloKey) {
              this.moduloKey = BigInteger.valueOf(moduloKey);
          }
      }
      

       
        [DONE] [View] [Reply] [Top]
        Posted by Lt CyberTNT On 2005-03-24 14:10:17
        Uploaded with Javadoc comments and Unit Tests.
         
      Java - MD5 - First Draft [View] [Reply] [Top]
      Posted by Maj anvar On 2005-03-14 19:01:39

      Ok, I found some time and decided to give MD5 a try, it does even give an output :), so feel free to comment.
      import java.security.MessageDigest;
      
      public class MD5 {
         public String getNameKey() {
              return "scheme.MD5.name";
          }
      
          public String getDescriptionKey() {
              return "scheme.MD5.description";
          }
      
          /**
           * Default method to run this.
           * @param input String -- The string we want to MD5.
           * @return String -- The result we get.
           */
          public String execute(String input) {
          
            if (input == null) return null;
            input = input.trim();
            if (input.length() == 0) return null;
            
            MessageDigest md = null;
            try {
               md = MessageDigest.getInstance("MD5");
            }
          
            // Eat the exception because it shouldn't happen.
            catch (Exception e) {
              return "Source-code Error";
            }
            // Input the text and return the MD5 into the result String.
            String result = new String(md.digest(input.getBytes()));
            return result;
          }
      }
      

       
        The working version (TM) :) [View] [Reply] [Top]
        Posted by Maj anvar On 2005-03-18 14:33:00

        Alright then, here's the working version. Thanks for pointing out that it were all hex value's (I must have been really sleeping back there :)
        I tested it with the tests supplyed at http://faqs.org/rfcs/rfc1321.html and they match, so I believe this version is working properly, although there is maybe some optimalisation to do.

        Comments/etc is welcomed. :)
        package net.cyberarmy.sneak.scheme;
        
        import net.cyberarmy.sneak.Scheme;
        import java.security.MessageDigest;
        
        public class MD5Scheme implements Scheme {
           public String getNameKey() {
                return "scheme.MD5.name";
            }
        
            public String getDescriptionKey() {
                return "scheme.MD5.description";
            }
        
            /**
             * Default method to run this.
             * @param input String -- The string we want to MD5.
             * @return String -- The result we get.
             */
            public String execute(String input) {
        
              if (input == null) return null;
              input = input.trim();
              if (input.length() == 0) return null;
        
              MessageDigest md = null;
              try {
                 md = MessageDigest.getInstance("MD5");
              }
        
              // Eat the exception because it shouldn't happen.
              catch (Exception e) {
                return "Source-code Error";
              }
        
              // Get the array of bytes representing the MD5 hash.
              byte[] bytes = md.digest(input.getBytes());
              StringBuffer md5 = new StringBuffer();
              // Loop through the array to get all the bytes, convert 
              // them to hex, and add them to our string.
              for (int i = 0; i < 16; i++) {
                md5.append(String.format("%02x", bytes[i]));
              }
               return md5.toString();
            }
        }
        

         
          RE: The working version (TM) :) [View] [Reply] [Top]
          Posted by Lt CyberTNT On 2005-03-18 15:05:54
          Looks good except the exception handeling and your trimming of whitespace characters. You shouldnt trim the array, as whitespace characters can be hashed too.

          On 2005-03-18 14:33:00, anvar wrote
          >
          >Alright then, here's the working version. Thanks for pointing out that it were all hex value's (I must have been really sleeping back there :)
          >I tested it with the tests supplyed at http://faqs.org/rfcs/rfc1321.html and they match, so I believe this version is working properly, although there is maybe some optimalisation to do.
          >
          >Comments/etc is welcomed. :)
          >
          >
          >package net.cyberarmy.sneak.scheme;
          >
          >import net.cyberarmy.sneak.Scheme;
          >import java.security.MessageDigest;
          >
          >public class MD5Scheme implements Scheme {
          >   public String getNameKey() {
          >        return "scheme.MD5.name";
          >    }
          >
          >    public String getDescriptionKey() {
          >        return "scheme.MD5.description";
          >    }
          >
          >    /**
          >     * Default method to run this.
          >     * @param input String -- The string we want to MD5.
          >     * @return String -- The result we get.
          >     */
          >    public String execute(String input) {
          >
          >      if (input == null) return null;
          >      input = input.trim();
          >      if (input.length() == 0) return null;
          >
          >      MessageDigest md = null;
          >      try {
          >         md = MessageDigest.getInstance("MD5");
          >      }
          >
          >      // Eat the exception because it shouldn't happen.
          >      catch (Exception e) {
          >        return "Source-code Error";
          >      }
          >
          >      // Get the array of bytes representing the MD5 hash.
          >      byte[] bytes = md.digest(input.getBytes());
          >      StringBuffer md5 = new StringBuffer();
          >      // Loop through the array to get all the bytes, convert 
          >      // them to hex, and add them to our string.
          >      for (int i = 0; i < 16; i++) {
          >        md5.append(String.format("%02x", bytes[i]));
          >      }
          >       return md5.toString();
          >    }
          >}
          >

           
            RE: The working version (TM) :) [View] [Reply] [Top]
            Posted by Maj anvar On 2005-03-18 16:02:48
            Ok, corrected version below:
            package net.cyberarmy.sneak.scheme;
            
            import net.cyberarmy.sneak.Scheme;
            import java.security.MessageDigest;
            import java.security.NoSuchAlgorithmException;
            
            public class MD5Scheme implements Scheme {
               public String getNameKey() {
                    return "scheme.MD5.name";
                }
            
                public String getDescriptionKey() {
                    return "scheme.MD5.description";
                }
            
                /**
                 * Default method to run this.
                 * @param input String -- The string we want to MD5.
                 * @return String -- The result we get.
                 */
                public String execute(String input) {
            
                  if (input == null) return null;
            
                  MessageDigest md = null;
                  try {
                     md = MessageDigest.getInstance("MD5");
                  }
            
                  // Eat the exception because it shouldn't happen.
                  catch (NoSuchAlgorithmException nse) {
                    return "Source-code Error";
                  }
            
                  // Get the array of bytes representing the MD5 hash.
                  byte[] bytes = md.digest(input.getBytes());
                  StringBuffer md5 = new StringBuffer();
                  // Loop through the array to get all the bytes, convert 
                  // them to hex, and add them to our string.
                  for (int i = 0; i < 16; i++) {
                    md5.append(String.format("%02x", bytes[i]));
                  }
                   return md5.toString();
                }
            }
            

             
              You cant use String.format... thats 1.5 only -nt- [View] [Reply] [Top]
              Posted by Ret. Gen D-Cypell On 2005-03-18 17:04:23

               
                2 questions [View] [Reply] [Top]
                Posted by Maj anvar On 2005-03-18 17:19:21

                This even tells me to download 1.5 https://www.cyberarmy.net/forum/sneak/messages/241638.html so if I should use 1.4 then I guess the guide is of.
                Also, if not String.format() then how else can I get this output (coz this is about the best way I could come up with).
                 
                  RE: 2 questions [View] [Reply] [Top]
                  Posted by Tr flamebalrog On 2005-03-24 22:41:05
                  >Also, if not String.format() then how else can I get this output (coz this is about the best way I could come up with).

                  mmhhh...proposed dirty way follows :
                  private String bytesToHexaString(byte[] byteArray) {
                      StringBuffer str=new StringBuffer(byteArray.length*2);
                      for (long i=0;i<byteArray.length;i++) {
                          int currentByte=byteArray[i];
                          if (currentByte<0)
                              currentByte+=256;
                          if (currentByte<16)
                              str.append('0');
                          str.append(Integer.toHexString(currentByte));
                      }
                      return str.toString();
                  }
                  Does it help ?


                   
                  RE: 2 questions [View] [Reply] [Top]
                  Posted by CinC snarkles On 2005-03-18 17:41:40
                  >This even tells me to download 1.5 https://www.cyberarmy.net/forum/sneak/messages/241638.html so if I should use 1.4 then I guess the guide is of.

                  Yep, sorry about that. I'm in the process of writing a new one which corrects errors in that document. It'll be hosted in the svn (should be more or less finished in the next day or so).

                  We have to stick to 1.4.2 because we recently discovered that not all operating systems (Mac OS X, for example) have a 1.5 JVM yet. This also will ensure better compatibility, as 1.5 has only been out for a little while and I'm not sure if it's considered stable yet.

                  Incidentally, if you ran the Ant build script after having added a call to a non-1.4 method (which should be done prior to submitting any code), it should've alerted you with an error message. Again, this procedure will be covered in the updated docs.

                  >Also, if not String.format() then how else can I get this output (coz this is about the best way I could come up with).

                  Not sure. :\ The method you used is fine, I'm just worried about cross-platform compatibility which was the whole point in using Java to begin with...so we're limited to only 1.4.2 stuff. We can look for an alternate way in the meantime, and if Sun releases 1.5 for more platforms in the meantime before we're ready for a "1.0 release" we can use this way.

                   
                  RE: 2 questions [View] [Reply] [Top]
                  Posted by Lt CyberTNT On 2005-03-18 17:41:38
                  On 2005-03-18 17:19:21, anvar wrote
                  >
                  >This even tells me to download 1.5 https://www.cyberarmy.net/forum/sneak/messages/241638.html so if I should use 1.4 then I guess the guide is of.

                  The guide is not off, if you would have used the ant build in eclipse, then it would have thrown an error message, about usage of 1.5 syntax. You can use whatever version of java you like, as long as the ant build runs successfully

                  >Also, if not String.format() then how else can I get this output (coz this is about the best way I could come up with).

                  Use the base conversion class when it is finished ^^
                   
        short note about it [View] [Reply] [Top]
        Posted by Maj anvar On 2005-03-15 18:27:03

        it isn't 100% working yet, for some reason the output is 16 char rather then 32, I'll be looking into it more, if any-one has suggestions, feel free to post :)
         
          RE: short note about it [View] [Reply] [Top]
          Posted by Lt CyberTNT On 2005-03-17 01:02:31
          well javas implementation works to 100%, just not your handling of the byte array. As faqs.org/rfcs/rfc1321.html states the output is in hex. So the byte array represents hex numbers. 8 bits = hex number with the length 2. Therefor 16 bytes = 16 hex numbers with a total length of 32. Therefor you get 32 chars.

           
          RE: short note about it [View] [Reply] [Top]
          Posted by Tr flamebalrog On 2005-03-16 23:20:17
          On 2005-03-15 18:27:03, anvar wrote
          >
          >it isn't 100% working yet, for some reason the output is 16 char rather then 32, I'll be looking into it more, if any-one has suggestions, feel free to post :)

          The digest() method returns an array of bytes.

          The String(byte[]) constructor makes a string by decoding the bytes array (using the platform's default charset...so this will not give the same results everywhere).

          I guess what you want isn't to decode the array, but rather convert it to an hex. representation of its bytes...

          Does it help ?

           
        Some things . . . [View] [Reply] [Top]
        Posted by Cpt SAJChurchey On 2005-03-14 19:22:49
        Just a few minor details here and there. Some refactoring. Do you know anything about JUnit tests? Someobody will have to write a test for this to be included. Just FYI.
        package net.cyberarmy.sneak.scheme;
        
        import net.cyberarmy.sneak.Scheme;
        import java.security.MessageDigest;
        
        public class MD5Scheme implements Scheme{
           public String getNameKey() {
                return "scheme.MD5.name";
            }
        
            public String getDescriptionKey() {
                return "scheme.MD5.description";
            }
        
            /**
             * Creates an MD5 digest of the input string
             * @param input String -- The string we want to MD5.
             * @return String -- The result we get.
             */
            public String execute(String input) {
            
              if (input == null) return null;
              input = input.trim();
              if (input.length() == 0) return null;
              
              MessageDigest md = null;
              try {
                 md = MessageDigest.getInstance("MD5");
              }
            
              // Eat the exception because it shouldn't happen.
              catch (Exception e) {
                return "Source-code Error";
              }
              // Input the text and return the MD5 into the result String.
              return new String(md.digest(input.getBytes()));
            }
        }
        

         
      Which GUI Library? [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-03-08 04:48:45
      I guess our main options here are AWT, Swing, and SWT. Between AWT and Swing, I would choose Swing. As far as SWT is concerned, will there be portability issues (specifically MacOS)?
       
      InvalidArgumentExceptions--How should we handle it [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-02-28 19:31:39
      What kind of error messages should the encryption/decryption methods report back to the client? I want to go ahead and code in the exception throws for the functions.

      I think w/ any null case, the exception message should be an empty string. No real processing is done, and the user probably submitted a null input on accident. It would probably be completely transparent, and the user would just think that it didn't do anything w/ an empty text field.

      All whitespace may be handled the same way.

      Invalid input in general, we should report back to the user exactly what kind of input we're looking for "binary digits, hex digits,UTF-16, etc." and that these sets should be separated by whitespace.
       
        Yeah, that would work... [View] [Reply] [Top]
        Posted by CinC snarkles On 2005-03-01 21:51:01
        We could even on the form use something along the lines of an OnKeyUp event to check and make sure there's something in the textarea prior to enabling the "Go" button. Though that wouldn't necessarily be portable to a commandline interface (although similar checks could be made there).

        With regard to the null/empty string check specifically (since it applies to *all* crypt methods), we should probably move that into a superclass (EncryptionScheme), and have an isValidInput() method which at that level only checks for null/empty string, but later subclasses (like Binary2Text) could override that method to check and make sure the input consisted of only 1s, 0s, and whitespace (for example) as well.

         
      Java - Bin2Text - Second Draft [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-02-24 20:22:31
      public static String Bin2Text(String str){
                if(str == null || str.trim().length() == 0)
                  return "";
                str = str.trim();
                if(str.matches("[^01\\s]")){
                      /*
                        User needs to be warned that their input is invalid
                        Method must terminate
                      */
                      return "";  //Until proper exception can be written
                }
                StringTokenizer tokenizedStr = new StringTokenizer(str);
                StringBuffer text = new StringBuffer();
                while(tokenizedStr.hasMoreTokens()){
                      String binaryString = tokenizedStr.nextToken();
                      int bytelen = binaryString.length();
                      if(bytelen > 16){
                       //User needs to be told input is not valid
                       return ""; //Until exception can be written.
                      }
                                      int intValue = bin2decimal(binaryString);
                      char textEquivalent = (char) intValue;
                      text.append(textEquivalent);
                }//end while
                return text.toString();
              }
      
              private static int bin2decimal(String binary){
                int decimal = 0;
                for(int i = binary.length() - 1;i >= 0;--i){
                      int asciiValue = binary.charAt(i) - '0';
                      decimal += Math.pow(2,i) * asciiValue;
                }//end for
                return decimal;
              }
      

       
        Added to SVN [View] [Reply] [Top]
        Posted by Cpt SAJChurchey On 2005-03-14 19:28:27
        As net.cyberarmy.sneak.scheme.TextToBinaryScheme, please feel free to submit patches.
         
        RE: Java - Bin2Text - Second Draft [View] [Reply] [Top]
        Posted by Tr flamebalrog On 2005-02-26 02:06:30
        On 2005-02-24 20:22:31, SAJChurchey wrote
        >
        >
        >        private static int bin2decimal(String binary){
        >          int decimal = 0;
        >          for(int i = binary.length() - 1;i >= 0;--i){
        >                int asciiValue = binary.charAt(i) - '0';
        >                decimal += Math.pow(2,i) * asciiValue;
        >          }//end for
        >          return decimal;
        >        }
        >

        Is Math.pow() faster than shift+or ?
        Also, the result is an integer, not a decimal. i.e. : naming the function bin2decimal could lead to misunderstanding (like decimal<==>represented with digits [0-9], which is probably not true 'coz I doubt an int is represented like that in memory...but I've never been in there so...).
                private static int bin2int(String binary){
                  int result = 0;
                  for(int i=0 ; i<binary.length ; i++) {
                        int bitValue = binary.charAt(i) - '0';
                        result=(result<<1)|bitValue;
                  }// avoid useless comments
                  return result;
                }
        

         
          Modified (Exceptions Included) [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-27 20:11:58
          Alright, I hope this looks better, it incorporates flamebalrog's bit shifts as opposed to using Math.pow() in the binary to integer conversion. I've also included the exceptions to be thrown if input is invalid. Not sure exactly what the message should be that is sent to the user though:
          public static String Bin2Text(String str){
                    if(str == null || str.matches("[^01\\s]"))
                      throw new IllegalArgumentException("Please insert binary digits separated by spaces");
                    str = str.trim();
                    if(str.length() == 0)
                      throw new IllegalArgumentException("Please insert binary digits separated by whitespace");
                    StringTokenizer tokenizedStr = new StringTokenizer(str);
                    StringBuffer text = new StringBuffer();
                    while(tokenizedStr.hasMoreTokens()){
                          String binaryString = tokenizedStr.nextToken();
                          int bytelen = binaryString.length();
                          if(bytelen > 16)
                            throw new IllegalArgumentException("Binary value outside of UTF-16 range");
                          int intValue = bin2int(binaryString);
                          char textEquivalent = (char) intValue;
                          text.append(textEquivalent);
                    }
                    return text.toString();
                  }
          
                  public static int bin2int(String binary){
                    int result = 0;
                    int numberBits = binary.length();
                    for(int i = 0;i < numberBits;++i){
                      int bitValue = binary.charAt(i) - '0';
                      result = (result<<1)|bitValue;
                    }//end for
                    return result;
                  }
          

           
            I'm evil... [View] [Reply] [Top]
            Posted by Tr flamebalrog On 2005-03-06 00:27:37
            Well, I gave you a possible way to speed things in your function, in the hope that you would be curious and search for a way to speed things up a bit more...

            If you didn't yet (I didn't check for the SVN repository yet), then I'll give you an advice (maybe the only one my Java knowledge allows me to give) : always have a copy of the API docs opened when coding and always read about classes you're manipulating. Your method returns an int ? Read about Integer. You method uses a Byte instance ? Read about Byte. And so on...

            After reading (about Integer), you'll see that Integer.parseInt(<yourBinaryStringHere>,2) could be used instead of an home made bin2int() method.
             
              You learn something new everyday (revision) [View] [Reply] [Top]
              Posted by Cpt SAJChurchey On 2005-03-07 21:37:56
              I had no idea you could do that w/ parseInt(). Thanx for that piece of info. The new code is:
              public static String Bin2Text(String str){
                        if(str == null || str.matches("[^01\\s]"))
                          throw new IllegalArgumentException("Please insert binary digits separated by spaces");
                        str = str.trim();
                        if(str.length() == 0)
                          throw new IllegalArgumentException("Please insert binary digits separated by whitespace");
                        StringTokenizer tokenizedStr = new StringTokenizer(str);
                        StringBuffer text = new StringBuffer();
                        while(tokenizedStr.hasMoreTokens()){
                              String binaryString = tokenizedStr.nextToken();
                              int bytelen = binaryString.length();
                              if(bytelen > 16)
                                throw new IllegalArgumentException("Binary value outside of UTF-16 range");
                              int intValue = Integer.parseInt(binaryString,2);
                              char textEquivalent = (char) intValue;
                              text.append(textEquivalent);
                        }
                        return text.toString();
                      }
              

               
          Bit shifts should be faster, thanx -nt- [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-26 19:19:48

           
      Java - Backwards - Second Draft [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-02-24 20:18:01
      public static String Backwards(String str){
            if(str == null || str.trim().equals(""))
              return "";
            str = str.trim();
            StringBuffer newString = new StringBuffer(str);
            return newString.reverse().toString();
      }
      

       
        Added to SVN [View] [Reply] [Top]
        Posted by Cpt SAJChurchey On 2005-03-14 19:29:48
        as net.cyberarmy.sneak.scheme.ReversalScheme please feel free to submit patches.
         
        RE: Java - Backwards - Second Draft [View] [Reply] [Top]
        Posted by Ret. Gen D-Cypell On 2005-02-26 19:22:23

        My version..
        public String backwards(String input)
        {
           if(input == null)
           {
               throw new IllegalArgumentException("null not supported");
           }
        
           StringBuffer buffer = new StringBuffer(input);
           buffer.reverse();
           return buffer.toString().trim();
        } 
        
        You can thrown in an empty string check if you like, it wont change the output and the performance benefit will be pretty negliable.

        Also in reality we should probably throw the exception when null is passed to any of the methods, rather than do this check every time, it would be best to factor it into the common superclass.

        On 2005-02-24 20:18:01, SAJChurchey wrote
        >
        >public static String Backwards(String str){
        >      if(str == null || str.trim().equals(""))
        >        return "";
        >      str = str.trim();
        >      StringBuffer newString = new StringBuffer(str);
        >      return newString.reverse().toString();
        >}
        >

         
          and factor trim() as well ? -nt- [View] [Reply] [Top]
          Posted by Tr flamebalrog On 2005-02-27 01:26:55

           
          In this case . . . [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-26 23:18:34
          The empty string check in this case is negligible, but what about in the other functions where a lot more operations are being performed on the data. I condensed some of the code and called trim() before reverse() was called, in case of input w/ large amounts of leading/trailing whitespace.
          public String backwards(String input)
          {
             if(input == null)
             {
                 throw new IllegalArgumentException("null not supported");
             }//end if
             StringBuffer buffer = new StringBuffer(input.trim());
             return buffer.reverse().toString();
          } 
          

           
        RE: Java - Backwards - Second Draft [View] [Reply] [Top]
        Posted by Lt dopel On 2005-02-26 16:51:44
        Maybe?
        public static String Backwards(String str){
              str = str.trim();
              if(str == null || str.equals("")){
                //Probably should throw some type of exception here
                return "";
              }
        
              StringBuffer newString = new StringBuffer(str);
              return newString.reverse().toString();
        }
        

         
          I had to take str=str.trim() out [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-26 19:16:27
          because if the string is null, it will through a NullPointerException. str must first be tested for null before any other functions can be performed on it. I had to use trim twice because I cannot do an assignment and check in the if statement. I could set up two separate if statements though:
          if(str == null)
            return "";
          str = str.trim();
          if(str.length() == 0)
            return "";
          
          Do you think that would be better?
           
          Nope.... [View] [Reply] [Top]
          Posted by Ret. Gen D-Cypell On 2005-02-26 19:14:49

          You have put the null pointer back. str = null will give you null pointer on the first line.

          On 2005-02-26 16:51:44, dopel wrote
          > Maybe?
          >
          >
          >public static String Backwards(String str){
          >      str = str.trim();
          >      if(str == null || str.equals("")){
          >        //Probably should throw some type of exception here
          >        return "";
          >      }
          >
          >      StringBuffer newString = new StringBuffer(str);
          >      return newString.reverse().toString();
          >}
          >

           
        RE: Java - Backwards - Second Draft [View] [Reply] [Top]
        Posted by Tr flamebalrog On 2005-02-26 02:15:52
        On 2005-02-24 20:18:01, SAJChurchey wrote
        >
        >public static String Backwards(String str){
        >      if(str == null || str.trim().equals(""))
        >        return "";
        >      str = str.trim();
        >      StringBuffer newString = new StringBuffer(str);
        >      return newString.reverse().toString();
        >}
        >

        A not-null-and-not-empty-and-not-space-only String (one that will be reversed) is trimmed twice with your code (1st to test it, 2nd after the test). You could avoid it.

        Also, I think ' "literalString".equals(expression) ' is faster than ' expression.equals("literalString") '...can anyone confirm ?
         
          Resolved [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-27 19:54:13
          There is updated code here to continue discussion on. I didn't originally intend to use equals, but I think a (str.trim().length() == 0) check would have been best for these circumstances. I decided to take the empty/whitespace string check out b/c there really is no benefit from doing the check w/ the function as simple as this.
           
          RE: Java - Backwards - Second Draft [View] [Reply] [Top]
          Posted by Ret. Gen D-Cypell On 2005-02-26 19:13:56

          Its not the fact that it is quicker that makes "literal".equals(str) a smart thing to do.

          The real reason is that it protects against null pointer exceptions. If str is null...

          str.equals("literal") will throw an NPE because you cant call .equals on null. If you put the literal first it obviously can never be null.

          In this case it doesnt matter too much because null is checked for anyway.

          On 2005-02-26 02:15:52, flamebalrog wrote
          >On 2005-02-24 20:18:01, SAJChurchey wrote
          >>
          >>public static String Backwards(String str){
          >>      if(str == null || str.trim().equals(""))
          >>        return "";
          >>      str = str.trim();
          >>      StringBuffer newString = new StringBuffer(str);
          >>      return newString.reverse().toString();
          >>}
          >>
          >
          >A not-null-and-not-empty-and-not-space-only String (one that will be reversed) is trimmed twice with your code (1st to test it, 2nd after the test). You could avoid it.
          >
          >Also, I think ' "literalString".equals(expression) ' is faster than ' expression.equals("literalString") '...can anyone confirm ?
           
            Thx for your input [bit more] [View] [Reply] [Top]
            Posted by Tr flamebalrog On 2005-02-27 23:01:18
            I was half asleep when posting this one and I don't know where, in my memory, I've found it could be faster...

            I suppose I've mixed different stuff and ended up giving an hint about a good (in some cases) practice with an advantage coming from another practice.

            Hopefully, you were here to save me (again) ;)
             
          RE: Java - Backwards - Second Draft [View] [Reply] [Top]
          Posted by Lt dopel On 2005-02-26 18:38:08
          As far a running time both are exactly the same, O(n). You have 2 string, one of length "n", the other of length "m." The worst case run time would be the shortest of the two, which is this case would be at most n. If there is some jvm optimization that makes one faster than the other, it would be on the order of milliseconds.


          On 2005-02-26 02:15:52, flamebalrog wrote
          >On 2005-02-24 20:18:01, SAJChurchey wrote
          >>
          >>public static String Backwards(String str){
          >>      if(str == null || str.trim().equals(""))
          >>        return "";
          >>      str = str.trim();
          >>      StringBuffer newString = new StringBuffer(str);
          >>      return newString.reverse().toString();
          >>}
          >>
          >
          >A not-null-and-not-empty-and-not-space-only String (one that will be reversed) is trimmed twice with your code (1st to test it, 2nd after the test). You could avoid it.
          >
          >Also, I think ' "literalString".equals(expression) ' is faster than ' expression.equals("literalString") '...can anyone confirm ?
           
      Java - Hex2Bin - First Draft [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-02-24 20:14:07

      When looking at this problem, you have to consider that we're not limited by a character set here. The user can type in an infinitely large expression to be converted, and as such this function needs to handle it. I thought of two different ways to accomplish this:

      1. Use the BigInteger class and do the conversion mathematically (hex -> decimal -> binary).

      2. Do a direct substitution, each hex digit has a unique nibble that can be directly substituted in.

      Considering that to do mathematical work w/ BigInteger you are working with a lot of BigInteger objects, and I figured the mathematical operations would slow the function down (Please correct me if I'm wrong).
      public static String hex2Bin(String str){
                if(str == null || str.trim().length() == 0)
                      return "";
                str = str.trim().toLowerCase();
                if(str.matches("[^0-9a-f\\s]"))
                      //InvalidInputException
                      return "";
                String[] nibbles = {
                                                              "0000",
                                                              "0001",
                                                              "0010",
                                                              "0011",
                                                              "0100",
                                                              "0101",
                                                              "0110",
                                                              "0111",
                                                              "1000",
                                                              "1001",
                                                              "1010", //a
                                                              "1011", //b
                                                              "1100", //c
                                                              "1101", //d
                                                              "1110", //e
                                                              "1111", //f
                                                       };
                int strLen = str.length();
                StringBuffer text = new StringBuffer(strLen * 4);
                for(int i = 0;i < strLen;++i){
                        int digit = str.charAt(i);
                        if(digit >= '0' && digit <= '9')
                              text.append(nibbles[digit - '0']);
                        else if(digit >= 'a' && digit <= 'f')
                              text.append(nibbles[digit - 'a' + 10]);
                        else
                              text.append((char) digit);
                }//end for
                return text.toString();
      }
      

       
      Java - Hex2Text - First Draft [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-02-24 20:07:17
      I had to write a separate conversion for hex -> decimal so that I could get the ascii value. I'm wondering whether or not I should do the same thing for the Bin2Text function.
      public static String hex2Text(String str){
                if(str == null || str.trim().length() == 0)
                  return "";
                str = str.trim();
                        str = str.toLowerCase();  //ensures all input is lower case
                if(str.matches("[^0-9a-f\\s]")){
                      /*
                        User needs to be warned that their input is invalid
                        Method must terminate
                      */
                      return "";  //Until proper exception can be written
                }
                StringTokenizer tokenizedStr = new StringTokenizer(str);
                StringBuffer text = new StringBuffer();
                while(tokenizedStr.hasMoreTokens()){
                      String hexString = tokenizedStr.nextToken();
                      int bytelen = hexString.length();
                      if(bytelen > 4){
                       //User needs to be told input is not valid
                       return ""; //Until exception can be written.
                      }
                      int  decimal = hex2decimal(hexString);
                      int intValue = 0;
                      for(int i = 0;i < strlen;++i){
                        int oneOrZero = decimal % 10;
                        decimal /= 10;
                        intValue += Math.pow(2,i) * oneOrZero;
                      }//end for
                      char textEquivalent = (char) intValue;
                      text.append(textEquivalent);
                }//end while
                return text.toString();
              }
      
              private static int hex2decimal(String hex){
                int decimal = 0;
                for(int i = hex.length() - 1;i >= 0;--i){
                      int asciiValue = hex.charAt(i);
                      if(asciiValue >= '0' && asciiValue <= '9')
                        asciiValue -= 48;
                      else{
                        asciiValue -= 87;
                  }
                      decimal += Math.pow(16,i) * asciiValue;
                }//end for
                return decimal;
              }//end hex2decimal()
      

       
        What about replacing hex2decimal() by... [View] [Reply] [Top]
        Posted by Tr flamebalrog On 2005-03-06 00:15:30
        ...a call to Integer.parseInt(<yourHexStringHere>,16) ?

         
          correction made [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-03-07 21:41:14
          public static String hex2Text(String str){
                    if(str == null || str.trim().length() == 0)
                      return "";
                    str = str.trim().toLowerCase();
                    if(str.matches("[^0-9a-f\\s]")){
                          /*
                            User needs to be warned that their input is invalid
                            Method must terminate
                          */
                          return "";  //Until proper exception can be written
                    }
                    StringTokenizer tokenizedStr = new StringTokenizer(str);
                    StringBuffer text = new StringBuffer();
                    while(tokenizedStr.hasMoreTokens()){
                          String hexString = tokenizedStr.nextToken();
                          int bytelen = hexString.length();
                          if(bytelen > 4){
                           //User needs to be told input is not valid
                           return ""; //Until exception can be written.
                          }
                          int  decimal = Integer.parseInt(hexString,16);
                          char textEquivalent = (char) decimal;
                          text.append(textEquivalent);
                    }//end while
                    return text.toString();
                  }
          

           
      Java - Text2Hex - First Draft [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-02-24 20:04:54
      The Hex conversions are pretty much the same as the binary conversions. All I had to do was change a few things here in there for the Hex case:
      public static String text2Hex(String str){
              if(str == null || str.trim().length() == 0)
                //Matches NULL and whitespace case
                return "";
              str = str.trim();  //Gets rid of leading/trailing whitespace
              int strlen = str.length();
              StringBuffer hexString = new StringBuffer((strlen * 3));
              /*
                Assuming all UTF-8 input.  The capacity of the buffer
                needs to be strlen * 3.  This cuts down on what can
                be a time consuming dynamic resizing on large input
                sets.  Should only resize once at most, and only if
                the input contains a UTF-16 character.
              */
              for(int i=0;i < strlen;++i){ //Iterates through string
                int decimal = str.charAt(i);  //Gets "ASCII value"
                String hex = Integer.toHexString(decimal);
                if(decimal <= 255){
                      /*
                        This case tests for ASCII, Extended ASCII and UTF-8
                        integer values.  It completes the octet for these
                        8-bit encodings by padding with leading zeros.
                      */
                      int trailingZeros = 2 - hex.length();
                      for(int j = 0; j < trailingZeros;++j)
                        hexString.append("0");
                }//end if
                else{ //UTF-16
                      /*
                        This case completes the 16-bit encoding of UTF-16
                        characters by padding with leading zeros
                      */
                      int trailingZeros = 4 - hex.length();
                      for(int k = 0;k < trailingZeros;++k)
                        hexString.append("0");
                }//end else
                hexString.append(hex);
                //Adds hexadecimal representation to generated leading zeros.
                hexString.append(" ");
         }//end for
         return hexString.toString();
      }//end text2Hex()
      

       
      Java - ASCII2Bin - Second Draft [View] [Reply] [Top]
      Posted by Cpt SAJChurchey On 2005-02-21 21:35:04
      Here's what could very well be the final version of the code. Take a look at it, and let's toss some ideas around.
      public static String string2Bin(String str){
              str.trim();  //Gets rid of leading/trailing whitespace
              if(str.matches("\\s+")) //Matches NULL and all white space
                return "";    //Short-circuits function
              int strlen = str.length();
              StringBuffer binaryString = new StringBuffer((strlen * 9));
              /*
                Assuming all UTF-8 input.  The capacity of the buffer
                needs to be strlen * 9.  This cuts down on what can
                be a time consuming dynamic resizing on large input
                sets.  Should only resize once at most, and only if
                the input contains a UTF-16 character.
              */
              for(int i=0;i < strlen;++i){ //Iterates through string
                int decimal = str.charAt(i);  //Gets "ASCII value"
                String binary = Integer.toBinaryString(decimal);
                if(decimal <= 255){
                      /*
                        This case tests for ASCII, Extended ASCII and UTF-8
                        integer values.  It completes the octet for these
                        8-bit encodings by padding with leading zeros.
                      */
                      int trailingZeros = 8 - binary.length();
                      for(int j = 0; j < trailingZeros;++j)
                        binaryString.append("0");
                }//end if
                else{ //UTF-16
                      /*
                        This case completes the 16-bit encoding of UTF-16
                        characters by padding with leading zeros
                      */
                      int trailingZeros = 16 - binary.length();
                      for(int k = 0;k < trailingZeros;++k)
                        binaryString.append("0");
                }//end else
                binaryString.append(binary);
                      //Adds binary representation to generated leading zeros.
            binaryString.append(" ");
         }//end for
         return binaryString.toString();
      }//end string2Bin()
      
      Thanks to Socrat (for the original implementation), D-Cypell (for good advice), and snarkles (for working out the test cases).
       
        Added to SVN [View] [Reply] [Top]
        Posted by Cpt SAJChurchey On 2005-03-14 19:31:00
        as net.cyberarmy.sneak.scheme.TextToBinaryScheme. Please feel free to submit patches.
         
        One thing . . . [View] [Reply] [Top]
        Posted by Cpt SAJChurchey On 2005-02-22 03:17:07
        trim() returns the trimmed string rather than just change the string so:
        public static String string2Bin(String str){
                str = str.trim();  //Gets rid of leading/trailing whitespace
                if(str.matches("\\s+")) //Matches NULL and all white space
                  return "";    //Short-circuits function
                int strlen = str.length();
                StringBuffer binaryString = new StringBuffer((strlen * 9));
                /*
                  Assuming all UTF-8 input.  The capacity of the buffer
                  needs to be strlen * 9.  This cuts down on what can
                  be a time consuming dynamic resizing on large input
                  sets.  Should only resize once at most, and only if
                  the input contains a UTF-16 character.
                */
                for(int i=0;i < strlen;++i){ //Iterates through string
                  int decimal = str.charAt(i);  //Gets "ASCII value"
                  String binary = Integer.toBinaryString(decimal);
                  if(decimal <= 255){
                        /*
                          This case tests for ASCII, Extended ASCII and UTF-8
                          integer values.  It completes the octet for these
                          8-bit encodings by padding with leading zeros.
                        */
                        int trailingZeros = 8 - binary.length();
                        for(int j = 0; j < trailingZeros;++j)
                          binaryString.append("0");
                  }//end if
                  else{ //UTF-16
                        /*
                          This case completes the 16-bit encoding of UTF-16
                          characters by padding with leading zeros
                        */
                        int trailingZeros = 16 - binary.length();
                        for(int k = 0;k < trailingZeros;++k)
                          binaryString.append("0");
                  }//end else
                  binaryString.append(binary);
                        //Adds binary representation to generated leading zeros.
              binaryString.append(" ");
           }//end for
           return binaryString.toString();
        }//end string2Bin()
        

         
          --regex [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-22 22:28:15
          public static String string2Bin(String str){
                  str = str.trim();  //Gets rid of leading/trailing whitespace
                  int strlen = str.length();
                  if(strlen == 0) //Matches NULL and all white space
                    return "";    //Short-circuits function
                  StringBuffer binaryString = new StringBuffer((strlen * 9));
                  /*
                    Assuming all UTF-8 input.  The capacity of the buffer
                    needs to be strlen * 9.  This cuts down on what can
                    be a time consuming dynamic resizing on large input
                    sets.  Should only resize once at most, and only if
                    the input contains a UTF-16 character.
                  */
                  for(int i=0;i < strlen;++i){ //Iterates through string
                    int decimal = str.charAt(i);  //Gets "ASCII value"
                    String binary = Integer.toBinaryString(decimal);
                    if(decimal <= 255){
                          /*
                            This case tests for ASCII, Extended ASCII and UTF-8
                            integer values.  It completes the octet for these
                            8-bit encodings by padding with leading zeros.
                          */
                          int trailingZeros = 8 - binary.length();
                          for(int j = 0; j < trailingZeros;++j)
                            binaryString.append("0");
                    }//end if
                    else{ //UTF-16
                          /*
                            This case completes the 16-bit encoding of UTF-16
                            characters by padding with leading zeros
                          */
                          int trailingZeros = 16 - binary.length();
                          for(int k = 0;k < trailingZeros;++k)
                            binaryString.append("0");
                    }//end else
                    binaryString.append(binary);
                          //Adds binary representation to generated leading zeros.
                binaryString.append(" ");
             }//end for
             return binaryString.toString();
          }//end string2Bin()
          

           
            NPE Fix [View] [Reply] [Top]
            Posted by Cpt SAJChurchey On 2005-02-23 19:42:04
            public static String string2Bin(String str){
                    if(str == null || str.trim().length() == 0)
                      //Matches NULL and whitespace case
                      return "";
                    str = str.trim();  //Gets rid of leading/trailing whitespace
                    int strlen = str.length();
                    StringBuffer binaryString = new StringBuffer((strlen * 9));
                    /*
                      Assuming all UTF-8 input.  The capacity of the buffer
                      needs to be strlen * 9.  This cuts down on what can
                      be a time consuming dynamic resizing on large input
                      sets.  Should only resize once at most, and only if
                      the input contains a UTF-16 character.
                    */
                    for(int i=0;i < strlen;++i){ //Iterates through string
                      int decimal = str.charAt(i);  //Gets "ASCII value"
                      String binary = Integer.toBinaryString(decimal);
                      if(decimal <= 255){
                            /*
                              This case tests for ASCII, Extended ASCII and UTF-8
                              integer values.  It completes the octet for these
                              8-bit encodings by padding with leading zeros.
                            */
                            int trailingZeros = 8 - binary.length();
                            for(int j = 0; j < trailingZeros;++j)
                              binaryString.append("0");
                      }//end if
                      else{ //UTF-16
                            /*
                              This case completes the 16-bit encoding of UTF-16
                              characters by padding with leading zeros
                            */
                            int trailingZeros = 16 - binary.length();
                            for(int k = 0;k < trailingZeros;++k)
                              binaryString.append("0");
                      }//end else
                      binaryString.append(binary);
                            //Adds binary representation to generated leading zeros.
                  binaryString.append(" ");
               }//end for
               return binaryString.toString();
            }//end string2Bin()
            

             
      For people writing drafts.... [View] [Reply] [Top]
      Posted by Ret. Gen D-Cypell On 2005-02-18 14:41:45

      Guys... firstly... excellent work on the draft algorithms here. Great to see some real gray matter churn on this board :o). I love this stuff!! :o)

      A point though... more important than posting up implementations of algorithms is posting up example inputs and expected outputs. The actually bit-shifting work can be done in many many many ways and in different languages, but what we really need is something we can use to TEST if the algorithm is working correctly. For example...

      L33tSpeak
      ---------------------

      Input: D-Cypell Rules
      Output: D-Cyp3ll Rul3z

      Provide a few of them before posting your algorithm. Then someone can come back and say ahhh... but for THIS input... <input here> I would expect this output <output here> but what I get from your code is <actually output>.

      When this occurs, we need to either correct the code or correct the expectation.

      What we need is as many example inputs and outputs as possible. When it comes to actually implementing the software we can write unit tests that will throw each example input at the algorithm and check that we got the expected output. This can be built into the build process so that every change is tested. If someone tweaks an algorithm for performance reasons they might break something and not realize, but thats OK... the tests will fail and we will know its broken.

      Hopefully I have adequetely express why the input output examples are more useful than the code. The code will change as things evolve but the input/output will remain far more static. Also it means that when we are discussing implementations we are all working with the same expectations.

      On 2005-02-15 17:19:31, snarkles wrote
      >his thread is to discuss the development of the desktop version of SNEAK.
       
        I can do these... [View] [Reply] [Top]
        Posted by CinC snarkles On 2005-02-19 15:15:23
        Just to eliminate multiple people from doing the same thing, I'm in the process of putting together a series of test cases for each function. Should be able to get it done by tonight.

         
          OK. Here's a start anyway... [View] [Reply] [Top]
          Posted by CinC snarkles On 2005-02-20 01:00:36
          SNEAK test cases

          I've created test cases for each of the 5 methods mentioned here.. will try to get to the rest of them tonight or tomorrow.

          I Googled "test cases" and found this site: http://readyset.tigris.org/words-of-wisdom/test-cases.html, which I used a guide (this is a completely wicked resource I wish I'd found earlier.. I caught all kinds of little stupid things I forgot :P).

          The only two that didn't really seem to fit (although this may be due to my understanding of the wording -- thanks muzzy for the help btw ;)) were:
          • syntactically legal: semantically legal and illegal values
          • syntactically illegal value: illegal characters or combinations
          This is because SNEAK should really be able to accept pretty much *any* keyboard input, for conversion purposes (I think.. feel free to prove me wrong ;)).

          Anyway, hope that was what you were looking for, DC.

           
            Eeek. Update... [View] [Reply] [Top]
            Posted by CinC snarkles On 2005-02-21 21:21:18
            The old version of the test cases threw in a UTF-16 character with UTF-8 characters on the "foreign characters" test. This one separates them out (although, come to think of it, I suppose "mixing" these could qualify as yet another test case).

            This was screwing up some people doing the ASCII->X methods, and should be fixed now. Let me know if you see any outstanding errors.

             
              Binary -> ASCII Test Cases [View] [Reply] [Top]
              Posted by Cpt SAJChurchey On 2005-02-22 01:52:49
              Any input other than 1s and 0s and the white space separating them should be thrown out b/c it's not binary. I think we need to write a RuntimeException to handle improper input on the user's part. The message with the exception should contain the proper type of input the user should enter, and we can use try-catch blocks to report the error to the user once we put all of this together.

              The zero case is correct, b/c zero in binary is zero in decimal, which is the NULL character on the ASCII table.

              Should we assume that the user's input will be easy to tokenize (1 - 16 0s or 1s separated by whitespace)? Otherwise, we risk not knowing when one character begins and another one ends b/c we're looking to try and support UTF-16 as well as UTF-8 and subsets thereof.
               
      Java - ASCII2Bin - First Draft [View] [Reply] [Top]
      Posted by Ker Socrat On 2005-02-17 20:09:14
      Ok, i managed to find how to change a character to its binary form with this code. The problem is , when i entered a normal character ( a or b or ^*&*( ;' ) its fine, it give the exact same result as the php SNEAK. but then i tryed with some ASCII like °&#9566;&#9575;&#9688;&#8596;¼èá4&#8597;ÿ and that messed up because on the php SNEAK version, the characters are converted back to #6365 or whatever their value is before they are converted to binary. But with this code they get converted for their real binary value, which is not what we want since they can be 15 chars long (1100101011110). So anyone knows how to modify it to check if its a "special" char and if it is convert to the #5646 value?
      	public static String string2Bin(String str){	
      		
      		String binaryString = new String();
      		for(int i=0;i<str.length();i++){
      			int decimal = str.charAt(i);
      			String binary = Integer.toBinaryString(decimal);
      			binaryString += " 0"+binary;
      		}
      		return binaryString;
      	}
      

       
        RE: Java - ASCII2Bin - First Draft [View] [Reply] [Top]
        Posted by Ret. Gen D-Cypell On 2005-02-18 14:32:32

        I want to make a couple of points on this particular function because it is a little trickier than the solution provided in this example and subsequent revisions in the thread.

        One of the stumbling blocks here is that Java's (and presumably C# and most other modern languages) char type consists of 2 bytes not 1. This is to provide support for UTF-16, or extended unicode. A quick description of character encoding... (if you already know this stuff, please dont get offended, someone else may not...)

        Obviously, the disk, memory etc is only capable of containing binary digits so to store text, we need a coversion table... enter ASCII...

        ASCII is a coversation table for numbers to letters and only uses 7-bits. This is why you are needing the prefix of "0" to bring it up to an even byte. 7-Bits were choosen because (when unsigned) we get the range 0-127 which is more than enough for all (latin alphabet) lowercase letters, uppercase letters, digits, punctuation and specials (like space and carriage return).

        Problem is, some characters in use in non-english speaking countries (and even some in the country that invented the damn language *cough*pound sign*cough*) were not included in the standard 0-127 ASCII table. Enter UTF-8... UTF-8 uses the whole 8-bit byte. Now we have 0-255 and space to include things like accented characters that appears in languages such as french and german.

        Its still not enough... what about the russians and the orientals and the other countries that dont use the latin alphabet. Guess what... UTF-16... two whole bytes and 0-131071 possible character codes. That is enough for all earth languages plus we can accomadate E.T., Predator and Darth Vader.

        Fortunately, ASCII is a subset of UTF-8 (i.e. any UTF-8 value that starts with a 0 is the same as the 7-bit ASCII), and (to my knowledge) UTF-8 is a subset of UTF-16 (if the most significant byte of UTF-16 is all 0 then its value is the same as UTF-8).

        So... before writing the code you have to decide what you want to do when UTF-8 is presented and even UTF-16.

        Its probably wise to have a fixed binary number length per character. So that if the input data is ASCII or UTF-8 you always get 8 binary digits per characters and if its UTF-16 you always get 16, but the java method toBinaryString will not give you this. That method will strip off any leading 0's so the strategy of just adding a 0 wont work. What you will have to do is check the length of the returned binary string and subtract this from how long you want the string to be (8 for UTF-8 or smaller, 16 for UTF-16), this will give you the number of 0's to append to the beginning. There is probably a better way to do this using the standard Java class library but i dont have that info in my head... I will look this up when required.

        On 2005-02-17 20:09:14, Socrat wrote
        >Ok, i managed to find how to change a character to its binary form with this code. The problem is , when i entered a normal character ( a or b or ^*&*( ;' ) its fine, it give the exact same result as the php SNEAK. but then i tryed with some ASCII like °&#9566;&#9575;&#9688;&#8596;¼èá4&#8597;ÿ and that messed up because on the php SNEAK version, the characters are converted back to #6365 or whatever their value is before they are converted to binary. But with this code they get converted for their real binary value, which is not what we want since they can be 15 chars long (1100101011110). So anyone knows how to modify it to check if its a "special" char and if it is convert to the #5646 value?
        >
        >
        >
        >	public static String string2Bin(String str){	
        >		
        >		String binaryString = new String();
        >		for(int i=0;i<str.length();i++){
        >			int decimal = str.charAt(i);
        >			String binary = Integer.toBinaryString(decimal);
        >			binaryString += " 0"+binary;
        >		}
        >		return binaryString;
        >	}
        >
        >

         
          How SNEAK deals w/ unicode . . . [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-19 16:57:24
          Well,

          From what I can gather, the PHP version of sneak will convert UTF-8 into binary if it is put in as an "ASCII" value. As far as UTF-16 is concerned, it substitutes the character in the text field w/ what I guess is an HTML code:

          À&#1331;&#1353; is changed to À&#1331;&#1353;

          &#1353; => &#1353;
          &#1331; => &#1331;

          Then, SNEAK analyzes each of the seven characters in the substituted code and adds them to the binary string that is reported.

          À&#1331;&#1353; => 11000000 00100110 00100011 00110001 00110011 00110011 00110001 00111011 00100110 00100011 00110001 00110011 00110101 00110011 00111011

          This is incorrect b/c UTF-16 is not made up of 7 bytes but 2, but then again this is an ASCII2Bin function not a UTF162Bin function. So we need to handle this special case in the same manner that SNEAK does, or should we improve the conversion capabilities if we can?

           
            By all means, go for improvement, imho... [View] [Reply] [Top]
            Posted by CinC snarkles On 2005-02-19 22:29:17
            One thing to realize that the bulk of this script was written about 5 years ago when I was basically just getting my feet wet in learning PHP (and programming in general, really). Funny story: my old text-to-binary converter used to be like 100 find/replace statements. *lol*

            Even in going through the script and making basic input/output charts, I'm finding all kinds of little things that I missed (it will try to convert a purely whitespace entry, there's no "maxlength" on the entry so someone could potentially throw 8MB worth of text in the script (please don't :P), etc.).

            So if you find areas like this where the current script seems "broken", always go for improving its capabilities if you can. Perhaps a check could be made initially on the characters entered to find out if they're UTF-8 or UTF-16, and call a different conversion method based on that.

            Though I'd maybe hold off on adding brand-new functionality (someone's mentioned PGP, UUEncoding, etc.) until after we get the base script up and running. If you have any questions on how/why something works the way it does, too, just ask and I'll do my best to answer. :)

             
              UTF162Bin instead of ASCII2Bin [View] [Reply] [Top]
              Posted by Cpt SAJChurchey On 2005-02-20 04:24:09
              Actually, I think the function as it stands will handle UTF-16, UTF-8 and ASCII characters as input and handle each. In fact, in the output, you should be able to tell UTF-16 binary code from the others b/c it is 16 bits instead of 8. No initial checks are necessary b/c it checks the integer value of the char to check to see if it is in UTF-8 range.
               
          Taking UTF-8 and UTF-16 into consideration . . . [View] [Reply] [Top]
          Posted by Cpt SAJChurchey On 2005-02-19 02:07:32
          I kept the StringBuffer stuff you had mentioned, and modified my code found here:
          public static String string2Bin(String str){	
          	StringBuffer binaryString = new StringBuffer();
                  int strlen = str.length();
          	for(int i=0;i < strlen;++i){ //faster loop
          		int decimal = str.charAt(i);
          		String binary = Integer.toBinaryString(decimal);
          		
          		if(decimal > -126 && decimal < 127){  //UTF-8
          			int trailingZeros = 8 - binary.length();
          			for(int i = 0; i < trailingZeros;++i)
          				binaryString.insert(0,"0");
          		}//end if
          		else{ //UTF-16
          			int trailingZeros = 16 - binary.length();
          			for(int i = 0;i < trailingZeros;++i)
          				binaryString.insert(0,"0");
          		}
          		binaryString.insert(0," ");
          		binaryString.append(binary);
          	}
          	return binaryString.toString();
          }
          

           
            RE: Taking UTF-8 and UTF-16 into consideration . . . [View] [Reply] [Top]
            Posted by Ker Socrat On 2005-02-19 03:16:21
            hmm you have errors in your code :P did you actually try this?
            Also your code will just add a space in FRONT of the string for each char entered, so if you enter a the result is fine but if you enter abcdefg you will get 7 spaces then the binary string. The code i submitted gave the same result as your code with a lot less coding.... if you run my code you will see that it gives back the righ binary value for any ascii charater even if its 16.
            you can initiate i twice in the same loop. you would need to change it to ::
            public static  String str2Bin(String str){
            			
            			StringBuffer binaryString = new StringBuffer();
            		        int strlen = str.length();
            			for(int i=0;i < strlen;++i){ //faster loop
            				int decimal = str.charAt(i);
            				String binary = Integer.toBinaryString(decimal);
            				
            				if(decimal > -126 && decimal < 127){  //UTF-8
            					int trailingZeros = 8 - binary.length();
            					for(int j = 0; i < trailingZeros;++i)
            						binaryString.insert(0,"0");
            				}//end if
            				else{ //UTF-16
            					int trailingZeros = 16 - binary.length();
            					for(int k = 0;i < trailingZeros;++i)
            						binaryString.insert(0,"0");
            				}
            				binaryString.insert(0," ");
            				binaryString.append(binary);
            			}
            			return binaryString.toString();
            		}
            
            that would make it work. But that is still not the result we wanna have. We want to get the actually numeric value of the ascii char like &#9576; <- that is a value, then we take each of those numbers and convert it to binary. That will give the same result as the php version.
             
              Where can I find the php version? (revision included) [View] [Reply] [Top]
              Posted by Cpt SAJChurchey On 2005-02-19 07:20:20
              so I can start running test cases. In the meantime, I've made some changes that should help out.
              	StringBuffer binaryString = new StringBuffer();
              	int strlen = str.length();
              	for(int i=0;i < strlen;++i){ //faster loop
              		int decimal = str.charAt(i);
              		String binary = Integer.toBinaryString(decimal);
              		if(decimal >= -126 && decimal <= 127){  //UTF-8
                                 //Needs to include the -126 and 127 values
              		  int trailingZeros = 8 - binary.length();
              		  for(int j = 0; j < trailingZeros;++j)
              			binaryString.append("0");
                                      //The StringBuffer is empty no need to insert()
              		}//end if
              		else{ //UTF-16
              	    	  int trailingZeros = 16 - binary.length();
              		  for(int k = 0;k < trailingZeros;++k)
              			binaryString.append("0");
              		}//end else
              		binaryString.append(" " + binary);
                              //Should space it out
              	     }
              	     return binaryString.toString();
                       }
              

               
                PHP version [View] [Reply] [Top]
                Posted by CinC snarkles On 2005-02-19 14:34:09
                There's a "live" version over at snarkles.net (also linked in the motd). You can also download the source there. The source of the current version is also in the subversion repository (also linked in the motd). Just use your CA username/password to access it. There are some pointers in the Welcome post on getting started with subversion, if you're not familiar with it.

                Hope that helps. :)

                 
                One more thing . . . [View] [Reply] [Top]
                Posted by Cpt SAJChurchey On 2005-02-19 07:45:13
                Sorry, it's been a few months since I've sat down to code. . . making minor mistakes here and there . . . Now the space should be printed after each binary representation (sets of 16 bits for UTF-16, and sets of 8 bits for UTF-8). I hope that brings us a little closer to what we're looking for. This is really the first time I've coded in a project this large, and the criticism is keeping me on my toes. I hope nobody is annoyed.
                	StringBuffer binaryString = new StringBuffer();
                	int strlen = str.length();
                	for(int i=0;i < strlen;++i){ //faster loop
                		int decimal = str.charAt(i);
                		String binary = Integer.toBinaryString(decimal);
                		if(decimal >= -126 && decimal <= 127){  //UTF-8
                                   //Needs to include the -126 and 127 values
                		  int trailingZeros = 8 - binary.length();
                		  for(int j = 0; j < trailingZeros;++j)
                			binaryString.append("0");
                                        //The StringBuffer is empty no need to insert()
                		}//end if
                		else{ //UTF-16
                	    	  int trailingZeros = 16 - binary.length();
                		  for(int k = 0;k < trailingZeros;++k)
                			binaryString.append("0");
                		}//end else
                		binaryString.append(binary);
                                binaryString.append(" ");  //Inserts space after binary is added to string
                	     }
                	     return binaryString.toString();
                         }
                

                 
                  After running the test cases . . . [View] [Reply] [Top]
                  Posted by Cpt SAJChurchey On 2005-02-21 19:29:29
                  A NULL string returns a NULL String. I hope this is what you mean by display error. Would it best to short-circuit the function so that it returns immediately if a NULL string is sent in as input:
                  public static String string2Bin(String str){
                    if(str.equals(""))
                       return;
                     /* rest of function code here */
                  
                  Also, are we ignoring whitespace altogether? A space as an ASCII value, too. If we're going by the test cases snarkles made some changes would have to be made:
                  public static String string2Bin(String str){
                    str.trim();
                    if(str.equals(""))
                       return;
                     /* rest of function code here */
                  
                  With foreign characters, the if-statement fails and falls into the UTF-16 case, where it appends 8 unnecessary zeros to the beginning of each binary value. I've double checked the ranges assuming a UTF-8 char can be contained in an 8-bit value (did I read this wrong?), but it's still not catching the if statement.

                  Everything else works with the above exceptions. Should I include the code to trim leading/trailing whitespace and short-circuit the function in the NULL case?
                   
                    Oh. . . and the changes I made this round [View] [Reply] [Top]
                    Posted by Cpt SAJChurchey On 2005-02-21 19:31:53
                    The one-byte ranges were wrong in the if statement . . .
                    public static String string2Bin(String str){
                            StringBuffer binaryString = new StringBuffer();
                            int strlen = str.length();
                            for(int i=0;i < strlen;++i){ //faster loop
                                    int decimal = str.charAt(i);
                                    String binary = Integer.toBinaryString(decimal);
                                    if(decimal >= -128 && decimal <= 127){  //UTF-8
                                       //Needs to include the -126 and 127 values
                                      int trailingZeros = 8 - binary.length();
                                      for(int j = 0; j < trailingZeros;++j)
                                            binaryString.append("0");
                                    }//end if
                                    else{ //UTF-16
                                      int trailingZeros = 16 - binary.length();
                                      for(int k = 0;k < trailingZeros;++k)
                                            binaryString.append("0");
                                    }//end else
                                    binaryString.append(binary);
                                    binaryString.append(" ");
                                 }
                                 return binaryString.toString();
                             }
                    }
                    

                     
                      Small clarifications [View] [Reply] [Top]
                      Posted by CinC snarkles On 2005-02-21 20:25:23
                      What I mean by display error is it should probably throw some kind of "NullStringException" or what have you that causes the UI to prompt them to re-enter their string (the current form says, "Fill in the form, dinglefritz! ;)" for example).

                      We don't want to ignore whitespace altogether (whitespace is important within text strings to separate words, paragraphs, etc.), but we *do* want to ignore trailing/leading whitespace, as in:
                      "    hello"
                      and
                      "hello        "
                      and also entries that are nothing *but* whitespace:
                      "                    "
                      So trim'ing the string prior to checking if it's empty should take care of those problems.

                      UTF-8 characters can go all the way up to 255 (8 bits). 127 and below are basic ASCII (7 bits)... 127-255 are extended ASCII (8 bits). Any higher than that (256-65535) and they require 2 bytes (16 bits) to hold the full value. So just change your if statement to check for
                      decimal <= 255
                      Btw, what's up with checking for negative decimal value?

                       
                        Hopefully, it'll work now . . . [View] [Reply] [Top]
                        Posted by Cpt SAJChurchey On 2005-02-21 20:56:32

                        What I mean by display error is it should probably throw some kind of "NullStringException" or what have you that causes the UI to prompt them to re-enter their string (the current form says, "Fill in the form, dinglefritz! ;)" for example).
                        Java won't have a problem printing the NULL string, at least it didn't when I ran the test cases. What will essentially happen is. . . nothing . . .such a request would not do anything b/c the function short-circuits. If you're dynamically changing a text field on a UI, the user won't know anything happened.

                        We don't want to ignore whitespace altogether (whitespace is important within text strings to separate words, paragraphs, etc.), but we *do* want to ignore trailing/leading whitespace, as in:
                        "    hello"
                        and
                        "hello        "
                        and also entries that are nothing *but* whitespace:
                        "                    "
                        So trim'ing the string prior to checking if it's empty should take care of those problems.
                        Including the trim and the NULL string case. . .

                        UTF-8 characters can go all the way up to 255 (8 bits). 127 and below are basic ASCII (7 bits)... 127-255 are extended ASCII (8 bits). Any higher than that (256-65535) and they require 2 bytes (16 bits) to hold the full value. So just change your if statement to check for
                        decimal <= 255
                        Btw, what's up with checking for negative decimal value?
                        I think I made the assumption that chars when cast to ints wound up signed instead of unsigned. Essentialy, it was to see if it was in the range of an 8-bit signed integer.
                        public static String string2Bin(String str){
                        public static String string2Bin(String str){
                                str.trim();
                                if(str.matches("\\s+"))
                                  return "";
                                StringBuffer binaryString = new StringBuffer();
                                int strlen = str.length();
                                for(int i=0;i < strlen;++i){ //faster loop
                                  int decimal = str.charAt(i);
                                  String binary = Integer.toBinaryString(decimal);
                                  if(decimal <= 255){  //UTF-8
                                        int trailingZeros = 8 - binary.length();
                                        for(int j = 0; j < trailingZeros;++j)
                                          binaryString.append("0");
                                  }//end if
                                  else{ //UTF-16
                                        int trailingZeros = 16 - binary.length();
                                        for(int k = 0;k < trailingZeros;++k)
                                          binaryString.append("0");
                                  }//end else
                                  binaryString.append(binary);
                              binaryString.append(" ");
                           }//end for
                           return binaryString.toString();
                        }//end string2Bin()
                        
                        I used a regular expression to match all whitespace and NULL cases.
                        I think it is either just giving the wrong answer for the first character of the Foreign Language case for whatever reason. Or there is something wrong w/ that particular test case. Can you double check it and get back to me?
                         
                  RE: One more thing . . . [View] [Reply] [Top]
                  Posted by Ker Socrat On 2005-02-19 16:47:32
                  lol, no worries man, same here. I say at least we are trying :P
                   
        RE: Java - ASCII2Bin - First Draft [View] [Reply] [Top]
        Posted by Lt CyberTNT On 2005-02-17 21:06:22
        i would suggest a base conversion function and another class which handles decimal <-> ascii
         
        RE: Java - ASCII2Bin - First Draft [View] [Reply] [Top]
        Posted by Cpt SAJChurchey On 2005-02-17 20:22:53
        I did some optimization on the loop. Calling the length() function through each iteration of the loop slows it down some, and pre-increment is faster as opposed to post-increment if it does not effect the algorithm.
        	public static String string2Bin(String str){	
        		
        		String binaryString = new String();
                        int strlen = str.length();
        		for(int i=0;i < strlen;++i){ //faster loop
        			int decimal = str.charAt(i);
        			String binary = Integer.toBinaryString(decimal);
        			binaryString += " 0"+binary;
        		}
        		return binaryString;
        	}
        
        What about
        binaryString += " 0" + binary
        
        Might that append unnecessary zeros in some places?
         
          RE: Java - ASCII2Bin - First Draft [View] [Reply] [Top]
          Posted by Ker Socrat On 2005-02-18 00:23:25
          What about

          binaryString += " 0" + binary

          Might that append unnecessary zeros in some places?


          Well, my goal was to have the exact same result as with the PHP SNEAK version. The goal is to have a 8 digit binary number as a result. Using only the Integer.toBinarySrting() method , the result is a 7 digit binary number. But its actually only missing a leading 0. I checked with all the characters on my keybord and got the same result as the PHP version. So i considered that a "working" version :) Aside from the ASCII character errors.

          If you have "the real" way to get 8 digits please post it here, its why this thread is named - FirstDraft - is because i got a part of it and i wanted to share it and complete it with some help.
           
            It makes sense [View] [Reply] [Top]
            Posted by Cpt SAJChurchey On 2005-02-18 01:46:36
            ASCII codes are positive integer values anyway, so a leading 0 makes sense. Not to mention 8-bits is an entire byte in binary as opposed to just 7.

             
          can you prove.... [View] [Reply] [Top]
          Posted by Lt CyberTNT On 2005-02-17 21:04:00
          that your "optimization" is actually faster than the previous code?
           
            An explanation . . . [View] [Reply] [Top]
            Posted by Cpt SAJChurchey On 2005-02-18 01:41:23
            Well,

            If you just think about it, each time through the for loop it has to check the conditional statement, and in order to do so it has to run the String.length() function, which is probably a few additional lines of code it has to run each time it checks the condition. As opposed to running the function one time and saving the value, it runs n times, where n is the number of characters. This can make a large amount of different w/ large input sets.

            As far as the post-increment/pre-increment thing, it has something to do w/ the processor. I know for a fact it works in C++, but I'm not sure whether or not the JVM changes that.

            Adequate?




             
              maybe DC can clear up things... [View] [Reply] [Top]
              Posted by Lt CyberTNT On 2005-02-18 09:53:05
              but i think JVM does support caching which could get you the same runtime.
               
                I will try... [View] [Reply] [Top]
                Posted by Ret. Gen D-Cypell On 2005-02-18 15:16:40

                Yes, the JVM will probably factor all of that out. There are quite a few different JVMs available and they will all do their optimization differently. Essentially the contract is... "We will run the code as you wrote it and will will attempt to run it as fast as possible". Without being an expert in the specific JVM (which is a full-time job) it is pretty difficult to say what it will optimize and what it wont.

                Removing the multiple calls to .length() will make a difference to performance but unless you are lt cmdr data you aint gonna notice (.length() just returns a precomputed int). I would be very surprised if the difference over a large loop was > 1ms. When dealing with optimizations that small it is far better to go with what is easier to read than what is faster because if your code saves you half a nanosecond but takes an extra 10 minutes to understand it isnt much of an optimization! I wont make judgements on what is easier to read though. Thats pretty subjective in this particular case.

                I have never heard of the prefix vs postfix incrementer issue but its sounds very very C like to me. I guess it makes sense as ++i says increment i first then use it for whatever... and i++ says use i for now... but i must remember to increment it when you are done. The first option sounds quicker, but I bet the JVM (even the compiler) factors this out too.

                The String concatenation will be a far bigger performance issue as string are immutable so the line
                binaryString += " 0"+binary
                will cause the creation of 2 strings ("0"+binary will be created, then a another new string which is the old binary string plus this). So if your input string has 500 characters then the code will create 1000 String objects, 1 will be returned and 999 will require garbage collection... and this takes far more time. StringBuffer will prevent this.

                On 2005-02-18 09:53:05, CyberTNT wrote
                >but i think JVM does support caching which could get you the same runtime.
                 
                  absolutly [View] [Reply] [Top]
                  Posted by Lt dopel On 2005-02-18 19:48:47
                  you are 100% correct on this. Unless n length of the string is very large, then amount of time will be negligable, however its good coding practice to only call a function once rather than each iteration of the loop. As far as the incriment. This is a constant time operation. Whatever is easies to read should be used.
                   
                    I do not think it effects the ease of read [View] [Reply] [Top]
                    Posted by Cpt SAJChurchey On 2005-02-18 20:27:02
                    at least not in this case, but there are certainly cases where it isn't.
                     
                      not to mention . . . [View] [Reply] [Top]
                      Posted by Cpt SAJChurchey On 2005-02-18 20:29:47
                      any large amount of code optimization is going to increase how difficult the code is to understand. That's probably why code optimization is done in the last phases of development. Not to mention, it's good practice to put in developer's comments to explain the intricacies of the algorithm.
                       
                  Version using StringBuffer [View] [Reply] [Top]
                  Posted by Cpt SAJChurchey On 2005-02-18 16:54:23
                  Thanks for the clarification DC. I'm going to go ahead and include those "optimizations," I'm also going to go ahead and use your StringBuffer suggestion. What's the best way to run benchmarks on this code? Code optimization interests me a lot.
                  public static String string2Bin(String str){	
                  	
                  	StringBuffer binaryString = new StringBuffer();
                          int strlen = str.length();
                  	for(int i=0;i < strlen;++i){ //faster loop
                  		int decimal = str.charAt(i);
                  		String binary = Integer.toBinaryString(decimal);
                  		binaryString.append(" 0");
                  		binaryString.append(binary);
                  	}
                  	return binaryString.toString();
                  }
                  
                  What about calculating the length the StringBuffer needs to be before the loop to cut down on dynamic resizing?
                   
      Java - rot13 method v1.0 - pre-approval [View] [Reply] [Top]
      Posted by Mar Tacheon On 2005-02-15 20:12:52
      I got bored, was looking through the php script and thought this would be an easy one to do. Should be able to make it so that you can specify the shift too, but not that bored (yet) ;) That and I haven't done any Java for a while.
      public class rot13 {
          
          private static char[] fromAlphabet = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}; 
          private static char[] toAlphabet   = {'n','o','p','q','r','s','t','u','v','w','x','y','z','a','b','c','d','e','f','g','h','i','j','k','l','m','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','A','B','C','D','E','F','G','H','I','J','K','L','M'};
      
          public static String toRot13 (String s){
              return convertString (s, fromAlphabet, toAlphabet);
          }
          
          private static String convertString (String s, char[] from, char[] to) {
              for(int i = 0; i < from.length; i++){ 
                  s = s.replaceAll(String.valueOf(from[i]), String.valueOf(to[i]));
              } 
              return s;
          }
          
      }
      

       
        RE: Java - rot13 method v1.0 - pre-approval [View] [Reply] [Top]
        Posted by Lt CyberTNT On 2005-02-16 10:53:39
        we can combine all substitution cipher (caesar, atbash, leet speak,....) in one class i guess.
         
          RE: Java - rot13 method v1.0 - pre-approval [View] [Reply] [Top]
          Posted by Ker Socrat On 2005-02-16 11:58:31
          No actually the plan if i remember correctly was to have 1 class per function. This is so that we can just stick a class in there without having to rearange anything.

          I think it would be better if we kept them separate.

          On 2005-02-16 10:53:39, CyberTNT wrote
          >we can combine all substitution cipher (caesar, atbash, leet speak,....) in one class i guess.
           
            RE: Java - rot13 method v1.0 - pre-approval [View] [Reply] [Top]
            Posted by Lt CyberTNT On 2005-02-16 13:24:36
            thats true for modern ciphers, but all substitution ciphers can be arranged in one class.
             
              RE: Java - rot13 method v1.0 - pre-approval [View] [Reply] [Top]
              Posted by Ker Socrat On 2005-02-16 13:33:50
              I know they "can" be , but when i discussed this with snarkles , i think we agreed(correct me if im wrong here snarks) but i think we agreed to make 1 class per method. I know this wasn't stated anywhere though. Maybe you could list the benefits of having them in the same class as opposed to separate classes?
               
                RE: Java - rot13 method v1.0 - pre-approval [View] [Reply] [Top]
                Posted by Ret. Gen D-Cypell On 2005-02-16 15:53:18
                Your requirement of 'one class per method' is pretty arbeitry, it is probably better to consider the actually design with a blank slate than to specify a series of design rules up front. In anycase, I would call 'Substitution cipher' as one 'method' anyway.

                Consider..
                public abstract class EncryptionScheme
                {
                    public abstract String encrypt(String source);
                }
                
                public class CipherEncryptionScheme extends EncryptionScheme
                {
                    private Cipher cipher;
                
                    public CipherEncryptionScheme(Cipher cipher)
                    {
                         this.cipher = cipher;    
                    }    
                
                    public String encrypt(String source)
                    {
                         return this.cipher.execute(source);
                    }
                }
                
                public abstract class Cipher
                {
                    public abstract String execute(String source); 
                }
                
                public class SubstitutionCipher extends Cipher
                { 
                    private char[] from;
                    private char[] to;  
                
                    public SubstitutionCipher(char[] from, char[] to)
                    {
                        this.from = from;
                        this.to = to;
                    }
                
                    public String execute(String source)
                    {
                        //Do the 'encryption' here, by performing the mapping
                    }
                }
                
                public class ShiftCipher extends Cipher
                {
                    private char[] shiftChars;
                    private int shiftDistance;
                
                    public ShiftCipher(char[] shiftChars, int shiftDistance)
                    {
                        this.shiftChars = shiftChars;
                        this.shiftDistance = shiftDistance;
                    }
                
                    public String execute(String source)
                    {
                        //Perform 'encryption' here, by finding all letters in the
                        //source string that are contained in the shiftChars and
                        //replacing them with shiftChar[index + shiftDistance]
                    }
                }
                
                Now you have a superclass of EncryptionScheme (which all encryption implementations extend). A subtype of CipherEncryptionScheme which works by running the source string through a cipher.

                You also have a Cipher superclass and I have created two different subtypes of cipher, one which takes two char[] and works by simply mapping from one array to another, and one which takes one char[] and a shift distance which will work by shifting down the cipher (like rot13).

                This is pretty flexible, and uses OOP in a much cleaner way.

                So I return your question back... what is the benefit of putting each encryption type in its own class when there is clear duplicate functionality that can be abstracted?

                On 2005-02-16 13:33:50, Socrat wrote
                >I know they "can" be , but when i discussed this with snarkles , i think we agreed(correct me if im wrong here snarks) but i think we agreed to make 1 class per method. I know this wasn't stated anywhere though. Maybe you could list the benefits of having them in the same class as opposed to separate classes?
                 
                  RE: Java - rot13 method v1.0 - pre-approval [View] [Reply] [Top]
                  Posted by Ker Socrat On 2005-02-16 18:13:29
                  Extendability is the benefit. If we do it each class in a separate file, the menu of the program could be created dynamically. If we create a new function, we can just stick the new class in there and generate a new jar. There would be no need to change anything. The way you are doing it would work best if this was a final version of a program you are the only one to work on. IMHO i think it is best to keep it simple. None of these functions (except maybe Smart Solver) is really complicated or will demand a lot of ressources.

                  Anyways, whatever way we go is fine with me, but i personnally prefer to keep things simple and dynamic. to me your superclass just adds an etra layer to something simple, but thats just me.
                   
                    lol oh geez... don't listen to me.. :P [View] [Reply] [Top]
                    Posted by CinC snarkles On 2005-02-16 22:49:35
                    D-Cypell has much more experience with OO design than I do, so please ignore everything I say in this regard. :P

                    I'll try to explain what I was originally thinking, and you can all point and laugh at my stupidity. ;D It'll be great fun!

                    Initially I thought the design would be simple... after all, all of the options in the list share one thing in common--they're all crypt methods! And I know that it's good practice to encapsulate parts of your project that are likely going to change often (and I'd like for it to be easy to add new crypt methods to SNEAK on a fairly regular basis).

                    So initially, I figured something simple like this (sorry, don't have Visio at home and I've long since forgotten how to print properly :P):



                    (I think this was around the time I talked with Socrat briefly)

                    Basically, all crypt methods inherit from the CryptMethod class (probably an abstract class or an interface), which provides a standard interface for encoding and decoding, so we could work in some kind of polymorphism later by calling encode/decode without knowing exactly what type of crypt method the user had selected until run-time (if that makes any sense ;P). Problem solved! ;)

                    Then it occurred to me that not all crypt methods are alike. For example:

                    The "Normal" Kind
                    - Base64
                    - HTML Entities
                    - l33tsp34k
                    - Pig Latin
                    - URL Encode/Decode

                    These all have separate encoding and decoding routines.

                    Self-Decoders
                    - ROT-13
                    - Backwards

                    Both of these don't need a special "decode" option.. the way to decode them is to run them through the same encryption again.

                    One-Way
                    - DES
                    - MD5

                    No way to decode these (unless we go for a bruteforce option in the offline version)

                    Numeric-Based
                    - ASCII <-> Binary
                    - ASCII <-> Hex
                    - Binary <-> Hex

                    All of these methods deal with numeric conversion in some way. You need to know what you're converting from and what you're converting to (so, two arguments).

                    Odd-ball
                    - Caesar

                    This one is sort of like the self-decoders, in that there's no real "decode" method.. just trying different shifts to see what works. But yet it needs to take an additional argument to know how far to shift.

                    So then I was looking at something more like this, at which point I decided "Um.. damn. I sure could use some help here." ;)



                    In any case, I think D-Cypell's right... Though the iniative is awesome to see, I think before we jump into coding parts of the desktop version, we should probably hammer out the d