import java.lang.Math;

/**
 * The xor password scrambler uses the xor
 * operator to mask passwords in your Java source code.
 * Use this when you want to embed a password in
 * your Java code but don't want a casual
 * observer of your code or your class
 * file to see it.
 * <p>
 * Understand that embedding passwords in a
 * program is always insecure no
 * matter how clever the scrambling method,
 * because the program contains
 * all the code needed to descramble it.
 * My technique provides only
 * protection against casual hackers.
 * For true security you must not embed
 * passwords in a program at all.
 * The user should type them in each time, or
 * use a ThumbDrive to store them.
 * @see http://mindprod.com/bgloss/thumbdrive.html
 * @author Roedy Green  copyright Canadian Mind Products 2005
 * may be used freely for any purpose but military.
 * version 1.0 2005-07-05
 **/

public class XorPWScrambler
   {

   /**
    * This is NOT the password. This is a scrambler phrase for the password.
    * The key used both to scramble and unscramble the password.
    * Just some pass phrase ideally
    * that blends into your program that looks like nothing special e.g.
    ( "error 576 : Token stack initialiser error."
    */
   static final char[] scrambler = "The universe is made of stories not atoms.".toCharArray();

   /**
    * You run this code once ahead of time to find out the string to embed
    * to represent the password. You later embed some of the code it generates
    * in your own program.
    *
    * @param put your real case-sensitive password
    * on the command line IN QUOTES!
    */
   public static void main ( String[] args )
      {
      if ( args.length != 1 )
         {
         throw new IllegalArgumentException (
                                            "You need to put your real password on the command line in quotes: e.g \"ali baba\"" );
         }

      // run this once ahead of time and note the output
      // and embed it in your code.
      // Look for output on the console
      scramble( args[0] );

      // embed the generated unscrambling code like the following
      // in your program leaving out the scramble method
      // code for extra security.
      // the embedded bit contains the magic scrambled numbers for
      // your real password. See if you can guess
      // what password I put on the original command line
      // without running the program, just by looking at the
      // source and the class file.

      // VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
      char[] scrambledPassword = new char[] {
         59,
         24,
         0,
         78,
         85,
         29,
         12,
         5,
         4,
         31,
         22,
      };
      String reconstitutedPassword = unscramble( scrambledPassword );
      // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

      out.println( "reconstituted: " +  reconstitutedPassword );

      }

   /**
    * display the magic numbers representing your scrambled password.
    * @param realPassword your actual password or passphrase you want to
    * scramble so you can more safely embed it in a program.
    * @return scrambled password as a String. Not much use since it
    * contains gibberish characters. See console for the
    * java code for a char[] representation
    */
   public static String scramble( String realPassword )
      {
      char[] thePasswordYouEmbed = xor( realPassword.toCharArray(), scrambler );

      // the scrambled password is full of gibberish non-printing chars .
      // We need to convert it to something human readable so we
      // print it out as code to insert with a list of ints, one per char
      out.println();
      out.println ( "char[] scrambledPassword = new char[] {" );

      for ( int i=0; i<thePasswordYouEmbed.length; i++ )
         {
         out.println ( (int)thePasswordYouEmbed[i] + "," );
         }
      out.println ( "};" );
      out.println ( "String reconstitutedPassword = unscramble( scrambledPassword );" );
      out.println();
      return new String( thePasswordYouEmbed );
      }

   /**
    * reconstitute a scrambled password
    * @param scrambledPassword an array of chars mostly unprintable.
    */
   public static String unscramble( char[] scrambledPassword )
      {
      // note you cannot use char[].toString()
      return new String ( xor( scrambledPassword, scrambler ) );
      }

   /**
    * @return xor of arrays a and b
    */
   public static char[] xor ( char[] a, char[] b )
      {
      int length = Math.min (a.length, b.length );
      char[] result = new char[length];
      for ( int i=0; i<length ; i++ )
         {
         // ^ is the xor operator
         // see http://mindprod.com/jgloss/xor.html
         result[i] = (char) ( a[i] ^ b[i] );
         }
      return result;
      }

   }