- 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;
+ }
+