Mass removal of all Tabs (Style Warnings)
[aaf/authz.git] / cadi / core / src / main / java / org / onap / aaf / cadi / Symm.java
index afc1d97..fd60b0c 100644 (file)
@@ -69,184 +69,184 @@ import org.onap.aaf.cadi.config.Config;
  *
  */
 public class Symm {
-       private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; 
-       public static final String ENC = "enc:";
-       private static final Object LOCK = new Object();
-       private static final SecureRandom random = new SecureRandom();
-       
-       public final char[] codeset;
-       private final int splitLinesAt;
-       private final String encoding;
-       private final Convert convert;
-       private final boolean endEquals;
-       private byte[] keyBytes = null;
-       //Note: AES Encryption is not Thread Safe.  It is Synchronized
-       //private AES aes = null;  // only initialized from File, and only if needed for Passwords
-       
-       /**
-        * This is the standard base64 Key Set.
-        * RFC 2045
-        */
-       public static final Symm base64 = new Symm(
-                       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray()
-                       ,76, Config.UTF_8,true);
-
-       public static final Symm base64noSplit = new Symm(
-                       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray()
-                       ,Integer.MAX_VALUE, Config.UTF_8,true);
-
-       /**
-        * This is the standard base64 set suitable for URLs and Filenames
-        * RFC 4648
-        */
-       public static final Symm base64url = new Symm(
-                       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".toCharArray()
-                       ,76, Config.UTF_8,true);
-
-       /**
-        * A Password set, using US-ASCII
-        * RFC 4648
-        */
-       public static final Symm encrypt = new Symm(base64url.codeset,1024, "US-ASCII", false);
-       private static final byte[] EMPTY = new byte[0];
-
-       /**
-        * A typical set of Password Chars
-        * Note, this is too large to fit into the algorithm. Only use with PassGen
-        */
-       private static char passChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!@#$%^&*(){}[]?:;,.".toCharArray();
-                       
-
-       private static Symm internalOnly = null;
-       
-       /**
-        * Use this to create special case Case Sets and/or Line breaks
-        
-        * If you don't know why you need this, use the Singleton Method
-        
-        * @param codeset
-        * @param split
-        */
-       public Symm(char[] codeset, int split, String charset, boolean useEndEquals) {
-               this.codeset = codeset;
-               splitLinesAt = split;
-               encoding = charset;
-               endEquals = useEndEquals;
-               char prev = 0, curr=0, first = 0;
-               int offset=Integer.SIZE; // something that's out of range for integer array
-               
-               // There can be time efficiencies gained when the underlying keyset consists mainly of ordered 
-               // data (i.e. abcde...).  Therefore, we'll quickly analyze the keyset.  If it proves to have
-               // too much entropy, the "Unordered" algorithm, which is faster in such cases is used.
-               ArrayList<int[]> la = new ArrayList<>();
-               for(int i=0;i<codeset.length;++i) {
-                       curr = codeset[i];
-                       if(prev+1==curr) { // is next character in set
-                               prev = curr;
-                       } else {
-                               if(offset!=Integer.SIZE) { // add previous range 
-                                       la.add(new int[]{first,prev,offset});
-                               }
-                               first = prev = curr;
-                               offset = curr-i;
-                       }
-               }
-               la.add(new int[]{first,curr,offset});
-               if(la.size()>codeset.length/3) {
-                       convert = new Unordered(codeset);
-               } else { // too random to get speed enhancement from range algorithm
-                       int[][] range = new int[la.size()][];
-                       la.toArray(range);
-                       convert = new Ordered(range);
-               }
-       }
-       
-       public Symm copy(int lines) {
-               return new Symm(codeset,lines,encoding,endEquals);
-       }
-       
-       // Only used by keygen, which is intentionally randomized. Therefore, always use unordered
-       private  Symm(char[] codeset, Symm parent) {
-               this.codeset = codeset;
-               splitLinesAt = parent.splitLinesAt;
-               endEquals = parent.endEquals;
-               encoding = parent.encoding;
-               convert = new Unordered(codeset);
-       }
-
-       /**
-        * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc.
-        * @return
-        */
-       @Deprecated
-       public static final Symm base64() {
-               return base64;
-       }
-
-       /**
-        * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc.  
-        * No Line Splitting
-        * @return
-        */
-       @Deprecated
-       public static final Symm base64noSplit() {
-               return base64noSplit;
-       }
-
-       /**
-        * Obtain the base64 "URL" behavior of this class, for use in File Names, etc. (no "/")
-        */
-       @Deprecated
-       public static final Symm base64url() {
-               return base64url;
-       }
-
-       /**
-        * Obtain a special ASCII version for Scripting, with base set of base64url use in File Names, etc. (no "/")
-        */
-       public static final Symm baseCrypt() {
-               return encrypt;
-       }
-
-       public <T> T exec(SyncExec<T> exec) throws Exception {
-               synchronized(LOCK) {
-                       if(keyBytes == null) {
-                               keyBytes = new byte[AES.AES_KEY_SIZE/8];
-                               int offset = (Math.abs(codeset[0])+47)%(codeset.length-keyBytes.length);
-                               for(int i=0;i<keyBytes.length;++i) {
-                                       keyBytes[i] = (byte)codeset[i+offset];
-                               }
-                       }
-               }
-               return exec.exec(new AES(keyBytes,0,keyBytes.length));
-       }
-       
-       public interface Encryption {
-               public CipherOutputStream outputStream(OutputStream os, boolean encrypt);
-               public CipherInputStream inputStream(InputStream is, boolean encrypt);
-       }
-
-       public static interface SyncExec<T> {
-               public T exec(Encryption enc) throws IOException, Exception;
-       }
-       
+    private static final byte[] DOUBLE_EQ = new byte[] {'=','='}; 
+    public static final String ENC = "enc:";
+    private static final Object LOCK = new Object();
+    private static final SecureRandom random = new SecureRandom();
+    
+    public final char[] codeset;
+    private final int splitLinesAt;
+    private final String encoding;
+    private final Convert convert;
+    private final boolean endEquals;
+    private byte[] keyBytes = null;
+    //Note: AES Encryption is not Thread Safe.  It is Synchronized
+    //private AES aes = null;  // only initialized from File, and only if needed for Passwords
+    
+    /**
+     * This is the standard base64 Key Set.
+     * RFC 2045
+     */
+    public static final Symm base64 = new Symm(
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray()
+            ,76, Config.UTF_8,true);
+
+    public static final Symm base64noSplit = new Symm(
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray()
+            ,Integer.MAX_VALUE, Config.UTF_8,true);
+
+    /**
+     * This is the standard base64 set suitable for URLs and Filenames
+     * RFC 4648
+     */
+    public static final Symm base64url = new Symm(
+            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_".toCharArray()
+            ,76, Config.UTF_8,true);
+
+    /**
+     * A Password set, using US-ASCII
+     * RFC 4648
+     */
+    public static final Symm encrypt = new Symm(base64url.codeset,1024, "US-ASCII", false);
+    private static final byte[] EMPTY = new byte[0];
+
+    /**
+     * A typical set of Password Chars
+     * Note, this is too large to fit into the algorithm. Only use with PassGen
+     */
+    private static char passChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+!@#$%^&*(){}[]?:;,.".toCharArray();
+            
+
+    private static Symm internalOnly = null;
+    
+    /**
+     * Use this to create special case Case Sets and/or Line breaks
+     * 
+     * If you don't know why you need this, use the Singleton Method
+     * 
+     * @param codeset
+     * @param split
+     */
+    public Symm(char[] codeset, int split, String charset, boolean useEndEquals) {
+        this.codeset = codeset;
+        splitLinesAt = split;
+        encoding = charset;
+        endEquals = useEndEquals;
+        char prev = 0, curr=0, first = 0;
+        int offset=Integer.SIZE; // something that's out of range for integer array
+        
+        // There can be time efficiencies gained when the underlying keyset consists mainly of ordered 
+        // data (i.e. abcde...).  Therefore, we'll quickly analyze the keyset.  If it proves to have
+        // too much entropy, the "Unordered" algorithm, which is faster in such cases is used.
+        ArrayList<int[]> la = new ArrayList<>();
+        for(int i=0;i<codeset.length;++i) {
+            curr = codeset[i];
+            if(prev+1==curr) { // is next character in set
+                prev = curr;
+            } else {
+                if(offset!=Integer.SIZE) { // add previous range 
+                    la.add(new int[]{first,prev,offset});
+                }
+                first = prev = curr;
+                offset = curr-i;
+            }
+        }
+        la.add(new int[]{first,curr,offset});
+        if(la.size()>codeset.length/3) {
+            convert = new Unordered(codeset);
+        } else { // too random to get speed enhancement from range algorithm
+            int[][] range = new int[la.size()][];
+            la.toArray(range);
+            convert = new Ordered(range);
+        }
+    }
+    
+    public Symm copy(int lines) {
+        return new Symm(codeset,lines,encoding,endEquals);
+    }
+    
+    // Only used by keygen, which is intentionally randomized. Therefore, always use unordered
+    private  Symm(char[] codeset, Symm parent) {
+        this.codeset = codeset;
+        splitLinesAt = parent.splitLinesAt;
+        endEquals = parent.endEquals;
+        encoding = parent.encoding;
+        convert = new Unordered(codeset);
+    }
+
+    /**
+     * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc.
+     * @return
+     */
+    @Deprecated
+    public static final Symm base64() {
+        return base64;
+    }
+
+    /**
+     * Obtain the base64() behavior of this class, for use in standard BASIC AUTH mechanism, etc.  
+     * No Line Splitting
+     * @return
+     */
+    @Deprecated
+    public static final Symm base64noSplit() {
+        return base64noSplit;
+    }
+
+    /**
+     * Obtain the base64 "URL" behavior of this class, for use in File Names, etc. (no "/")
+     */
+    @Deprecated
+    public static final Symm base64url() {
+        return base64url;
+    }
+
+    /**
+     * Obtain a special ASCII version for Scripting, with base set of base64url use in File Names, etc. (no "/")
+     */
+    public static final Symm baseCrypt() {
+        return encrypt;
+    }
+
+    public <T> T exec(SyncExec<T> exec) throws Exception {
+        synchronized(LOCK) {
+            if(keyBytes == null) {
+                keyBytes = new byte[AES.AES_KEY_SIZE/8];
+                int offset = (Math.abs(codeset[0])+47)%(codeset.length-keyBytes.length);
+                for(int i=0;i<keyBytes.length;++i) {
+                    keyBytes[i] = (byte)codeset[i+offset];
+                }
+            }
+        }
+        return exec.exec(new AES(keyBytes,0,keyBytes.length));
+    }
+    
+    public interface Encryption {
+        public CipherOutputStream outputStream(OutputStream os, boolean encrypt);
+        public CipherInputStream inputStream(InputStream is, boolean encrypt);
+    }
+
+    public static interface SyncExec<T> {
+        public T exec(Encryption enc) throws IOException, Exception;
+    }
+    
     public byte[] encode(byte[] toEncrypt) throws IOException {
-               if(toEncrypt==null) {
-                       return EMPTY;
-               } else {
-                       ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(toEncrypt.length*1.25));
-                       encode(new ByteArrayInputStream(toEncrypt),baos);
-                       return baos.toByteArray();
-               }
-       }
+            if(toEncrypt==null) {
+                return EMPTY;
+            } else {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(toEncrypt.length*1.25));
+            encode(new ByteArrayInputStream(toEncrypt),baos);
+            return baos.toByteArray();
+            }
+    }
 
     public byte[] decode(byte[] encrypted) throws IOException {
-               ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(encrypted.length*1.25));
-               decode(new ByteArrayInputStream(encrypted),baos);
-               return baos.toByteArray();
-       }
+        ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(encrypted.length*1.25));
+        decode(new ByteArrayInputStream(encrypted),baos);
+        return baos.toByteArray();
+    }
 
-       /**
+    /**
      *  Helper function for String API of "Encode"
      *  use "getBytes" with appropriate char encoding, etc.
      *  
@@ -255,22 +255,22 @@ public class Symm {
      * @throws IOException
      */
     public String encode(String str) throws IOException {
-       byte[] array;
-               boolean useDefaultEncoding = false;
-       try { 
-               array = str.getBytes(encoding);
-       } catch (IOException e) {
-               array = str.getBytes(); // take default
-                       useDefaultEncoding = true;
-       }
-       // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code
-       ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*1.363)); // account for 4 bytes for 3 and a byte or two more
-       
-       encode(new ByteArrayInputStream(array),baos);
-               if (useDefaultEncoding) {
-                       return baos.toString();
-               }
-               return baos.toString(encoding);
+        byte[] array;
+        boolean useDefaultEncoding = false;
+        try { 
+            array = str.getBytes(encoding);
+        } catch (IOException e) {
+            array = str.getBytes(); // take default
+            useDefaultEncoding = true;
+        }
+        // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code
+        ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*1.363)); // account for 4 bytes for 3 and a byte or two more
+        
+        encode(new ByteArrayInputStream(array),baos);
+        if (useDefaultEncoding) {
+            return baos.toString();
+        }
+        return baos.toString(encoding);
     }
     
     /**
@@ -281,24 +281,24 @@ public class Symm {
      * @throws IOException
      */
     public String decode(String str) throws IOException {
-       byte[] array;
-               boolean useDefaultEncoding = false;
-       try { 
-               array = str.getBytes(encoding);
-       } catch (IOException e) {
-               array = str.getBytes(); // take default
-                       useDefaultEncoding = true;
-       }
-       // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code
-       ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*.76)); // Decoding is 3 bytes for 4.  Allocate slightly more than 3/4s
-       decode(new ByteArrayInputStream(array), baos);
-               if (useDefaultEncoding) {
-                       return baos.toString();
-               }
-       return baos.toString(encoding);
-       }
-
-       /**
+        byte[] array;
+        boolean useDefaultEncoding = false;
+        try { 
+            array = str.getBytes(encoding);
+        } catch (IOException e) {
+            array = str.getBytes(); // take default
+            useDefaultEncoding = true;
+        }
+        // Calculate expected size to avoid any buffer expansion copies within the ByteArrayOutput code
+        ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(array.length*.76)); // Decoding is 3 bytes for 4.  Allocate slightly more than 3/4s
+        decode(new ByteArrayInputStream(array), baos);
+        if (useDefaultEncoding) {
+            return baos.toString();
+        }
+        return baos.toString(encoding);
+    }
+
+    /**
      * Convenience Function
      * 
      * encode String into InputStream and call encode(InputStream, OutputStream)
@@ -307,29 +307,29 @@ public class Symm {
      * @param out
      * @throws IOException
      */
-       public void encode(String string, OutputStream out) throws IOException {
-               encode(new ByteArrayInputStream(string.getBytes()),out);
-       }
-
-       /**
-        * Convenience Function
-        
-        * encode String into InputStream and call decode(InputStream, OutputStream)
-        
-        * @param string
-        * @param out
-        * @throws IOException
-        */
-       public void decode(String string, OutputStream out) throws IOException {
-               decode(new ByteArrayInputStream(string.getBytes()),out);
-       }
+      public void encode(String string, OutputStream out) throws IOException {
+          encode(new ByteArrayInputStream(string.getBytes()),out);
+    }
+
+    /**
+     * Convenience Function
+     * 
+     * encode String into InputStream and call decode(InputStream, OutputStream)
+     * 
+     * @param string
+     * @param out
+     * @throws IOException
+     */
+    public void decode(String string, OutputStream out) throws IOException {
+        decode(new ByteArrayInputStream(string.getBytes()),out);
+    }
 
     public void encode(InputStream is, OutputStream os, byte[] prefix) throws IOException {
-       os.write(prefix);
-       encode(is,os);
+        os.write(prefix);
+        encode(is,os);
     }
 
-       /** 
+    /** 
      * encode InputStream onto Output Stream
      * 
      * @param is
@@ -338,95 +338,95 @@ public class Symm {
      * @throws IOException
      */
     public void encode(InputStream is, OutputStream os) throws IOException {
-       // StringBuilder sb = new StringBuilder((int)(estimate*1.255)); // try to get the right size of StringBuilder from start.. slightly more than 1.25 times 
-       int prev=0;
-       int read, idx=0, line=0;
-       boolean go;
-       do {
-               read = is.read();
-               if(go = read>=0) {
-                       if(line>=splitLinesAt) {
-                               os.write('\n');
-                               line = 0;
-                       }
-                       switch(++idx) { // 1 based reading, slightly faster ++
-                               case 1: // ptr is the first 6 bits of read
-                                       os.write(codeset[read>>2]);
-                                       prev = read;
-                                       break;
-                               case 2: // ptr is the last 2 bits of prev followed by the first 4 bits of read
-                                       os.write(codeset[((prev & 0x03)<<4) | (read>>4)]);
-                                       prev = read;
-                                       break;
-                               default: //(3+) 
-                                               // Char 1 is last 4 bits of prev plus the first 2 bits of read
-                                           // Char 2 is the last 6 bits of read
-                                       os.write(codeset[(((prev & 0xF)<<2) | (read>>6))]);
-                                       if(line==splitLinesAt) { // deal with line splitting for two characters
-                                               os.write('\n');
-                                               line=0;
-                                       }
-                                       os.write(codeset[(read & 0x3F)]);
-                                       ++line;
-                                       idx = 0;
-                                       prev = 0;
-                       }
-                       ++line;
-               } else { // deal with any remaining bits from Prev, then pad
-                       switch(idx) {
-                               case 1: // just the last 2 bits of prev
-                                       os.write(codeset[(prev & 0x03)<<4]);
-                                       if(endEquals)os.write(DOUBLE_EQ);
-                                       break;
-                               case 2: // just the last 4 bits of prev
-                                       os.write(codeset[(prev & 0xF)<<2]);
-                                       if(endEquals)os.write('=');
-                                       break;
-                       }
-                       idx = 0;
-               }
-               
-       } while(go);
+        // StringBuilder sb = new StringBuilder((int)(estimate*1.255)); // try to get the right size of StringBuilder from start.. slightly more than 1.25 times 
+        int prev=0;
+        int read, idx=0, line=0;
+        boolean go;
+        do {
+            read = is.read();
+            if(go = read>=0) {
+                if(line>=splitLinesAt) {
+                    os.write('\n');
+                    line = 0;
+                }
+                switch(++idx) { // 1 based reading, slightly faster ++
+                    case 1: // ptr is the first 6 bits of read
+                        os.write(codeset[read>>2]);
+                        prev = read;
+                        break;
+                    case 2: // ptr is the last 2 bits of prev followed by the first 4 bits of read
+                        os.write(codeset[((prev & 0x03)<<4) | (read>>4)]);
+                        prev = read;
+                        break;
+                    default: //(3+) 
+                            // Char 1 is last 4 bits of prev plus the first 2 bits of read
+                            // Char 2 is the last 6 bits of read
+                        os.write(codeset[(((prev & 0xF)<<2) | (read>>6))]);
+                        if(line==splitLinesAt) { // deal with line splitting for two characters
+                            os.write('\n');
+                            line=0;
+                        }
+                        os.write(codeset[(read & 0x3F)]);
+                        ++line;
+                        idx = 0;
+                        prev = 0;
+                }
+                ++line;
+            } else { // deal with any remaining bits from Prev, then pad
+                switch(idx) {
+                    case 1: // just the last 2 bits of prev
+                        os.write(codeset[(prev & 0x03)<<4]);
+                        if(endEquals)os.write(DOUBLE_EQ);
+                        break;
+                    case 2: // just the last 4 bits of prev
+                        os.write(codeset[(prev & 0xF)<<2]);
+                        if(endEquals)os.write('=');
+                        break;
+                }
+                idx = 0;
+            }
+            
+        } while(go);
     }
 
     public void decode(InputStream is, OutputStream os, int skip) throws IOException {
-       if(is.skip(skip)!=skip) {
-               throw new IOException("Error skipping on IOStream in Symm");
-       }
-       decode(is,os);
+        if(is.skip(skip)!=skip) {
+            throw new IOException("Error skipping on IOStream in Symm");
+        }
+        decode(is,os);
     }
 
     /**
-        * Decode InputStream onto OutputStream
-        * @param is
-        * @param os
-        * @throws IOException
-        */
+     * Decode InputStream onto OutputStream
+     * @param is
+     * @param os
+     * @throws IOException
+     */
     public void decode(InputStream is, OutputStream os) throws IOException {
-          int read, idx=0;
-          int prev=0, index;
-               while((read = is.read())>=0) {
-                       index = convert.convert(read);
-                       if(index>=0) {
-                       switch(++idx) { // 1 based cases, slightly faster ++
-                               case 1: // index goes into first 6 bits of prev
-                                       prev = index<<2; 
-                                       break;
-                               case 2: // write second 2 bits of into prev, write byte, last 4 bits go into prev
-                                       os.write((byte)(prev|(index>>4)));
-                                       prev = index<<4;
-                                       break;
-                               case 3: // first 4 bits of index goes into prev, write byte, last 2 bits go into prev
-                                       os.write((byte)(prev|(index>>2)));
-                                       prev = index<<6;
-                                       break;
-                               default: // (3+) | prev and last six of index
-                                       os.write((byte)(prev|(index&0x3F)));
-                                       idx = prev = 0;
-                       }
-                       }
-               };
-               os.flush();
+       int read, idx=0;
+       int prev=0, index;
+           while((read = is.read())>=0) {
+               index = convert.convert(read);
+               if(index>=0) {
+                switch(++idx) { // 1 based cases, slightly faster ++
+                    case 1: // index goes into first 6 bits of prev
+                        prev = index<<2; 
+                        break;
+                    case 2: // write second 2 bits of into prev, write byte, last 4 bits go into prev
+                        os.write((byte)(prev|(index>>4)));
+                        prev = index<<4;
+                        break;
+                    case 3: // first 4 bits of index goes into prev, write byte, last 2 bits go into prev
+                        os.write((byte)(prev|(index>>2)));
+                        prev = index<<6;
+                        break;
+                    default: // (3+) | prev and last six of index
+                        os.write((byte)(prev|(index&0x3F)));
+                        idx = prev = 0;
+                }
+               }
+           };
+           os.flush();
    }
    
    /**
@@ -435,7 +435,7 @@ public class Symm {
     *
     */
    private interface Convert {
-          public int convert(int read) throws IOException;
+       public int convert(int read) throws IOException;
    }
 
    /**
@@ -445,27 +445,27 @@ public class Symm {
     *
     */
    private static final class Ordered implements Convert {
-          private int[][] range;
-          public Ordered(int[][] range) {
-                  this.range = range;
-          }
-          public int convert(int read) throws IOException {
-                  // System.out.print((char)read);
-                  switch(read) {
-                          case -1: 
-                          case '=':
-                          case ' ':
-                          case '\n':
-                          case '\r':
-                                  return -1;
-                  }
-                  for(int i=0;i<range.length;++i) {
-                          if(read >= range[i][0] && read<=range[i][1]) {
-                                  return read-range[i][2];
-                          }
-                  }
-                  throw new IOException("Unacceptable Character in Stream");
-          }
+       private int[][] range;
+       public Ordered(int[][] range) {
+           this.range = range;
+       }
+       public int convert(int read) throws IOException {
+           // System.out.print((char)read);
+           switch(read) {
+               case -1: 
+               case '=':
+               case ' ':
+               case '\n':
+               case '\r':
+                   return -1;
+           }
+           for(int i=0;i<range.length;++i) {
+               if(read >= range[i][0] && read<=range[i][1]) {
+                   return read-range[i][2];
+               }
+           }
+           throw new IOException("Unacceptable Character in Stream");
+       }
    }
    
    /**
@@ -475,24 +475,24 @@ public class Symm {
     *
     */
    private static final class Unordered implements Convert {
-          private char[] codec;
-          public Unordered(char[] codec) {
-                  this.codec = codec;
-          }
-          public int convert(int read) throws IOException {
-                  switch(read) {
-                          case -1: 
-                          case '=':
-                                case '\n':
-                                case '\r':
-                                  return -1;
-                  }
-                  for(int i=0;i<codec.length;++i) {
-                          if(codec[i]==read)return i;
-                  }
-                 // don't give clue in Encryption mode
-                 throw new IOException("Unacceptable Character in Stream");
-          }
+       private char[] codec;
+       public Unordered(char[] codec) {
+           this.codec = codec;
+       }
+       public int convert(int read) throws IOException {
+           switch(read) {
+               case -1: 
+               case '=':
+                 case '\n':
+                 case '\r':
+                   return -1;
+           }
+           for(int i=0;i<codec.length;++i) {
+               if(codec[i]==read)return i;
+           }
+          // don't give clue in Encryption mode
+          throw new IOException("Unacceptable Character in Stream");
+       }
    }
 
    /**
@@ -502,34 +502,34 @@ public class Symm {
     * @throws IOException
     */
    public static byte[] keygen() throws IOException {
-               byte inkey[] = new byte[0x600];
-               new SecureRandom().nextBytes(inkey);
-               ByteArrayOutputStream baos = new ByteArrayOutputStream(0x800);
-               base64url.encode(new ByteArrayInputStream(inkey), baos);
-               return baos.toByteArray();
+        byte inkey[] = new byte[0x600];
+        new SecureRandom().nextBytes(inkey);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(0x800);
+        base64url.encode(new ByteArrayInputStream(inkey), baos);
+        return baos.toByteArray();
    }
    
    // A class allowing us to be less predictable about significant digits (i.e. not picking them up from the
    // beginning, and not picking them up in an ordered row.  Gives a nice 2048 with no visible patterns.
    private class Obtain {
-          private int last;
-          private int skip;
-          private int length;
-          private byte[] key;
+       private int last;
+       private int skip;
+       private int length;
+       private byte[] key;
   
-          private Obtain(Symm b64, byte[] key) {
-                  skip = Math.abs(key[key.length-13]%key.length);
-                  if((key.length&0x1) == (skip&0x1)) { // if both are odd or both are even
-                          ++skip;
-                  }
-                  length = b64.codeset.length;
-                  last = 17+length%59; // never start at beginning
-                  this.key = key;
-          }
-          
-          private int next() {
-                  return Math.abs(key[(++last*skip)%key.length])%length;
-          }
+       private Obtain(Symm b64, byte[] key) {
+           skip = Math.abs(key[key.length-13]%key.length);
+           if((key.length&0x1) == (skip&0x1)) { // if both are odd or both are even
+               ++skip;
+           }
+           length = b64.codeset.length;
+           last = 17+length%59; // never start at beginning
+           this.key = key;
+       }
+       
+       private int next() {
+             return Math.abs(key[(++last*skip)%key.length])%length;
+       }
    };
   
    /**
@@ -541,55 +541,55 @@ public class Symm {
  * @throws CadiException 
     */
    public static Symm obtain(Access access) throws CadiException {
-               String keyfile = access.getProperty(Config.CADI_KEYFILE,null);
-               if(keyfile!=null) {
-                       Symm symm = Symm.baseCrypt();
-
-                       File file = new File(keyfile);
-                       try {
-                               access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getCanonicalPath());
-                       } catch (IOException e1) {
-                               access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getAbsolutePath());
-                       }
-                       if(file.exists()) {
-                               try {
-                                       FileInputStream fis = new FileInputStream(file);
-                                       try {
-                                               symm = Symm.obtain(fis);
-                                       } finally {
-                                               try {
-                                                  fis.close();
-                                               } catch (IOException e) {
-                                               }
-                                       }
-                               } catch (IOException e) {
-                                       access.log(e, "Cannot load keyfile");
-                               }
-                       } else {
-                               String filename;
-                               try {
-                                       filename = file.getCanonicalPath();
-                               } catch (IOException e) {
-                                       filename = file.getAbsolutePath();
-                               }
-                               throw new CadiException("ERROR: " + filename + " does not exist!");
-                       }
-                       return symm;
-               } else {
-                       try {
-                               return internalOnly();
-                       } catch (IOException e) {
-                               throw new CadiException(e);
-                       }
-               }
+        String keyfile = access.getProperty(Config.CADI_KEYFILE,null);
+        if(keyfile!=null) {
+            Symm symm = Symm.baseCrypt();
+
+            File file = new File(keyfile);
+            try {
+                access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getCanonicalPath());
+            } catch (IOException e1) {
+                access.log(Level.INIT, Config.CADI_KEYFILE,"points to",file.getAbsolutePath());
+            }
+            if(file.exists()) {
+                try {
+                    FileInputStream fis = new FileInputStream(file);
+                    try {
+                        symm = Symm.obtain(fis);
+                    } finally {
+                        try {
+                           fis.close();
+                        } catch (IOException e) {
+                        }
+                    }
+                } catch (IOException e) {
+                    access.log(e, "Cannot load keyfile");
+                }
+            } else {
+                String filename;
+                try {
+                    filename = file.getCanonicalPath();
+                } catch (IOException e) {
+                    filename = file.getAbsolutePath();
+                }
+                throw new CadiException("ERROR: " + filename + " does not exist!");
+            }
+            return symm;
+        } else {
+            try {
+                return internalOnly();
+            } catch (IOException e) {
+                throw new CadiException(e);
+            }
+        }
    }
   /**
    *  Create a new random key 
    */
   public Symm obtain() throws IOException {
-               byte inkey[] = new byte[0x800];
-               new SecureRandom().nextBytes(inkey);
-               return obtain(inkey);
+        byte inkey[] = new byte[0x800];
+        new SecureRandom().nextBytes(inkey);
+        return obtain(inkey);
   }
   
   /**
@@ -600,7 +600,7 @@ public class Symm {
    * @throws IOException
    */
   public static Symm obtain(String key) throws IOException {
-         return obtain(new ByteArrayInputStream(key.getBytes()));
+      return obtain(new ByteArrayInputStream(key.getBytes()));
   }
   
   /**
@@ -611,18 +611,18 @@ public class Symm {
    * @throws IOException
    */
   public static Symm obtain(InputStream is) throws IOException {
-         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-         try {
-                 base64url.decode(is, baos);
-         } catch (IOException e) {
-                 // don't give clue
-                 throw new IOException("Invalid Key");
-         }
-         byte[] bkey = baos.toByteArray();
-         if(bkey.length<0x88) { // 2048 bit key
-                 throw new IOException("Invalid key");
-         }
-         return baseCrypt().obtain(bkey);
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      try {
+          base64url.decode(is, baos);
+      } catch (IOException e) {
+          // don't give clue
+          throw new IOException("Invalid Key");
+      }
+      byte[] bkey = baos.toByteArray();
+      if(bkey.length<0x88) { // 2048 bit key
+          throw new IOException("Invalid key");
+      }
+      return baseCrypt().obtain(bkey);
   }
 
   /**
@@ -633,12 +633,12 @@ public class Symm {
    * @throws IOException
    */
   public static Symm obtain(File f) throws IOException {
-         FileInputStream fis = new FileInputStream(f);
-         try {
-                 return obtain(fis);
-         } finally {
-                 fis.close();
-         }
+      FileInputStream fis = new FileInputStream(f);
+      try {
+          return obtain(fis);
+      } finally {
+          fis.close();
+      }
   }
   /**
    * Decrypt into a String
@@ -650,9 +650,9 @@ public class Symm {
    * @throws IOException
    */
   public String enpass(String password) throws IOException {
-         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-         enpass(password,baos);
-         return new String(baos.toByteArray());
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      enpass(password,baos);
+      return new String(baos.toByteArray());
   }
 
   /**
@@ -663,65 +663,65 @@ public class Symm {
    * @throws IOException
    */
   public void enpass(final String password, final OutputStream os) throws IOException {
-           if(password==null) {
-               throw new IOException("Invalid password passed");
-           }
-               final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               DataOutputStream dos = new DataOutputStream(baos);
-               byte[] bytes = password.getBytes();
-               if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization
-                       dos.write(bytes);
-               } else {
-                       
-                       Random r = new SecureRandom();
-                       int start = 0;
-                       byte b;
-                       for(int i=0;i<3;++i) {
-                               dos.writeByte(b=(byte)r.nextInt());
-                               start+=Math.abs(b);
-                       }
-                       start%=0x7;
-                       for(int i=0;i<start;++i) {
-                               dos.writeByte(r.nextInt());
-                       }
-                       dos.writeInt((int)System.currentTimeMillis());
-                       int minlength = Math.min(0x9,bytes.length);
-                       dos.writeByte(minlength); // expect truncation
-                       if(bytes.length<0x9) {
-                               for(int i=0;i<bytes.length;++i) {
-                                       dos.writeByte(r.nextInt());
-                                       dos.writeByte(bytes[i]);
-                               }
-                               // make sure it's long enough
-                               for(int i=bytes.length;i<0x9;++i) {
-                                       dos.writeByte(r.nextInt());
-                               }
-                       } else {
-                               dos.write(bytes);
-                       }
-               }
-               
-               // 7/21/2016 Jonathan add AES Encryption to the mix
-               try {
-                       exec(new SyncExec<Void>() {
-                               @Override
-                               public Void exec(Encryption enc) throws Exception {
-                                       CipherInputStream cis = enc.inputStream(new ByteArrayInputStream(baos.toByteArray()), true);
-                                       try {
-                                               encode(cis,os);
-                                       } finally {
-                                               os.flush();
-                                               cis.close();
-                                       }
-                                       return null;
-                               }
-                       });
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException(e);
-               }
-       }
+        if(password==null) {
+            throw new IOException("Invalid password passed");
+        }
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        DataOutputStream dos = new DataOutputStream(baos);
+        byte[] bytes = password.getBytes();
+        if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization
+            dos.write(bytes);
+        } else {
+            
+            Random r = new SecureRandom();
+            int start = 0;
+            byte b;
+            for(int i=0;i<3;++i) {
+                dos.writeByte(b=(byte)r.nextInt());
+                start+=Math.abs(b);
+            }
+            start%=0x7;
+            for(int i=0;i<start;++i) {
+                dos.writeByte(r.nextInt());
+            }
+            dos.writeInt((int)System.currentTimeMillis());
+            int minlength = Math.min(0x9,bytes.length);
+            dos.writeByte(minlength); // expect truncation
+            if(bytes.length<0x9) {
+                for(int i=0;i<bytes.length;++i) {
+                    dos.writeByte(r.nextInt());
+                    dos.writeByte(bytes[i]);
+                }
+                // make sure it's long enough
+                for(int i=bytes.length;i<0x9;++i) {
+                    dos.writeByte(r.nextInt());
+                }
+            } else {
+                dos.write(bytes);
+            }
+        }
+        
+        // 7/21/2016 Jonathan add AES Encryption to the mix
+        try {
+            exec(new SyncExec<Void>() {
+                @Override
+                public Void exec(Encryption enc) throws Exception {
+                    CipherInputStream cis = enc.inputStream(new ByteArrayInputStream(baos.toByteArray()), true);
+                    try {
+                        encode(cis,os);
+                    } finally {
+                        os.flush();
+                        cis.close();
+                    }
+                    return null;
+                }
+            });
+        } catch (IOException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
 
   /**
    * Decrypt a password into a String
@@ -733,10 +733,10 @@ public class Symm {
    * @throws IOException
    */
   public String depass(String password) throws IOException {
-         if(password==null)return null;
-         ByteArrayOutputStream baos = new ByteArrayOutputStream();
-         depass(password,baos);
-         return new String(baos.toByteArray());
+      if(password==null)return null;
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      depass(password,baos);
+      return new String(baos.toByteArray());
   }
   
   /**
@@ -750,68 +750,68 @@ public class Symm {
    * @throws IOException
    */
   public long depass(final String password, final OutputStream os) throws IOException {
-         int offset = password.startsWith(ENC)?4:0;
-         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-         final ByteArrayInputStream bais =  new ByteArrayInputStream(password.getBytes(),offset,password.length()-offset);
-         try {
-               exec(new SyncExec<Void>() {
-                       @Override
-                       public Void exec(Encryption enc) throws IOException {
-                                 CipherOutputStream cos = enc.outputStream(baos, false);
-                                 decode(bais,cos);
-                                 cos.close(); // flush
-                                 return null;
-                       }
-                 });
-               } catch (IOException e) {
-                       throw e;
-               } catch (Exception e) {
-                       throw new IOException(e);
-               }
-
-         byte[] bytes = baos.toByteArray();
-         DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
-         long time;
-         if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization
-                 os.write(bytes);
-                 time = 0L;
-         } else {
-                 int start=0;
-                 for(int i=0;i<3;++i) {
-                         start+=Math.abs(dis.readByte());
-                 }
-                 start%=0x7;
-                 for(int i=0;i<start;++i) {
-                         dis.readByte();
-                 }
-                 time = (dis.readInt() & 0xFFFF)|(System.currentTimeMillis()&0xFFFF0000);
-                 int minlength = dis.readByte();
-                 if(minlength<0x9){
-                       DataOutputStream dos = new DataOutputStream(os);
-                       for(int i=0;i<minlength;++i) {
-                               dis.readByte();
-                               dos.writeByte(dis.readByte());
-                       }
-                 } else {
-                         int pre =((Byte.SIZE*3+Integer.SIZE+Byte.SIZE)/Byte.SIZE)+start; 
-                         os.write(bytes, pre, bytes.length-pre);
-                 }
-         }
-         return time;
+      int offset = password.startsWith(ENC)?4:0;
+      final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      final ByteArrayInputStream bais =  new ByteArrayInputStream(password.getBytes(),offset,password.length()-offset);
+      try {
+        exec(new SyncExec<Void>() {
+            @Override
+            public Void exec(Encryption enc) throws IOException {
+                  CipherOutputStream cos = enc.outputStream(baos, false);
+                  decode(bais,cos);
+                  cos.close(); // flush
+                  return null;
+            }
+          });
+        } catch (IOException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+
+      byte[] bytes = baos.toByteArray();
+      DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
+      long time;
+      if(this.getClass().getSimpleName().startsWith("base64")) { // don't expose randomization
+          os.write(bytes);
+          time = 0L;
+      } else {
+          int start=0;
+          for(int i=0;i<3;++i) {
+              start+=Math.abs(dis.readByte());
+          }
+          start%=0x7;
+          for(int i=0;i<start;++i) {
+              dis.readByte();
+          }
+          time = (dis.readInt() & 0xFFFF)|(System.currentTimeMillis()&0xFFFF0000);
+          int minlength = dis.readByte();
+          if(minlength<0x9){
+            DataOutputStream dos = new DataOutputStream(os);
+            for(int i=0;i<minlength;++i) {
+                dis.readByte();
+                dos.writeByte(dis.readByte());
+            }
+          } else {
+              int pre =((Byte.SIZE*3+Integer.SIZE+Byte.SIZE)/Byte.SIZE)+start; 
+              os.write(bytes, pre, bytes.length-pre);
+          }
+      }
+      return time;
   }
 
   public static String randomGen(int numBytes) {
-         return randomGen(passChars,numBytes);  
+      return randomGen(passChars,numBytes);  
   }
   
   public static String randomGen(char[] chars ,int numBytes) {
-           int rint;
-           StringBuilder sb = new StringBuilder(numBytes);
-           for(int i=0;i<numBytes;++i) {
-               rint = random.nextInt(chars.length);
-               sb.append(chars[rint]);
-           }
-           return sb.toString();
+        int rint;
+        StringBuilder sb = new StringBuilder(numBytes);
+        for(int i=0;i<numBytes;++i) {
+            rint = random.nextInt(chars.length);
+            sb.append(chars[rint]);
+        }
+        return sb.toString();
   }
   // Internal mechanism for helping to randomize placement of characters within a Symm codeset
   // Based on an incoming data stream (originally created randomly, but can be recreated within 
@@ -821,52 +821,52 @@ public class Symm {
   // shuffled for a good spread. It is, however, repeatable, given the same number set, allowing for 
   // quick recreation when the official stream is actually obtained.
   public Symm obtain(byte[] key) throws IOException {
-         int filled = codeset.length;
-         char[] seq = new char[filled];
-         int end = filled--;
-
-         boolean right = true;
-         int index;
-         Obtain o = new Obtain(this,key);
-
-         while(filled>=0) {
-                 index = o.next();
-                 if(index<0 || index>=codeset.length) {
-                         System.out.println("uh, oh");
-                 }
-                 if(right) { // alternate going left or right to find the next open slot (keeps it from taking too long to hit something) 
-                         for(int j=index;j<end;++j) {
-                                 if(seq[j]==0) {
-                                         seq[j]=codeset[filled];
-                                         --filled;
-                                         break;
-                                 }
-                         }
-                         right = false;
-                 } else {
-                         for(int j=index;j>=0;--j) {
-                                 if(seq[j]==0) {
-                                         seq[j]=codeset[filled];
-                                         --filled;
-                                         break;
-                                 }
-                         }
-                         right = true;
-                 }
-         }
-         Symm newSymm = new Symm(seq,this);
-         // Set the KeyBytes
-         try {
-                 newSymm.keyBytes = new byte[AES.AES_KEY_SIZE/8];
-                 int offset = (Math.abs(key[(47%key.length)])+137)%(key.length-newSymm.keyBytes.length);
-                 for(int i=0;i<newSymm.keyBytes.length;++i) {
-                         newSymm.keyBytes[i] = key[i+offset];
-                 }
-         } catch (Exception e) {
-                 throw new IOException(e);
-         }
-
-         return newSymm;
+      int filled = codeset.length;
+      char[] seq = new char[filled];
+      int end = filled--;
+
+      boolean right = true;
+      int index;
+      Obtain o = new Obtain(this,key);
+
+      while(filled>=0) {
+          index = o.next();
+          if(index<0 || index>=codeset.length) {
+              System.out.println("uh, oh");
+          }
+          if(right) { // alternate going left or right to find the next open slot (keeps it from taking too long to hit something) 
+              for(int j=index;j<end;++j) {
+                  if(seq[j]==0) {
+                      seq[j]=codeset[filled];
+                      --filled;
+                      break;
+                  }
+              }
+              right = false;
+          } else {
+              for(int j=index;j>=0;--j) {
+                  if(seq[j]==0) {
+                      seq[j]=codeset[filled];
+                      --filled;
+                      break;
+                  }
+              }
+              right = true;
+          }
+      }
+      Symm newSymm = new Symm(seq,this);
+      // Set the KeyBytes
+      try {
+          newSymm.keyBytes = new byte[AES.AES_KEY_SIZE/8];
+          int offset = (Math.abs(key[(47%key.length)])+137)%(key.length-newSymm.keyBytes.length);
+          for(int i=0;i<newSymm.keyBytes.length;++i) {
+              newSymm.keyBytes[i] = key[i+offset];
+          }
+      } catch (Exception e) {
+          throw new IOException(e);
+      }
+
+      return newSymm;
   }
   
   /** 
@@ -876,14 +876,14 @@ public class Symm {
  * @throws IOException 
    */
   public static synchronized Symm internalOnly() throws IOException {
-         if(internalOnly==null) {
-                 ByteArrayInputStream baos = new ByteArrayInputStream(keygen());
-                 try {
-                         internalOnly = Symm.obtain(baos);
-                 } finally {
-                         baos.close();
-                 }
-         }
-         return internalOnly;
+      if(internalOnly==null) {
+          ByteArrayInputStream baos = new ByteArrayInputStream(keygen());
+          try {
+              internalOnly = Symm.obtain(baos);
+          } finally {
+              baos.close();
+          }
+      }
+      return internalOnly;
   }
 }