Java tutorial
/* * Copyright © 2011 Rebecca G. Bettencourt / Kreative Software * <p> * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * <a href="http://www.mozilla.org/MPL/">http://www.mozilla.org/MPL/</a> * <p> * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * <p> * Alternatively, the contents of this file may be used under the terms * of the GNU Lesser General Public License (the "LGPL License"), in which * case the provisions of LGPL License are applicable instead of those * above. If you wish to allow use of your version of this file only * under the terms of the LGPL License and not to allow others to use * your version of this file under the MPL, indicate your decision by * deleting the provisions above and replace them with the notice and * other provisions required by the LGPL License. If you do not delete * the provisions above, a recipient may use your version of this file * under either the MPL or the LGPL License. * @since OpenXION 1.3 * @author Rebecca G. Bettencourt, Kreative Software */ //package com.kreative.openxion.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.text.CharacterIterator; import java.text.StringCharacterIterator; /** * The Base64 utility class implements Base-64 and Base-85 encoding and decoding algorithms. * @since OpenXION 1.3 * @author Rebecca G. Bettencourt, Kreative Software */ public class Base64 { private Base64() { } private static final char[] b64e = { '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', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', }; public static String encodeBase64(byte[] b, int off, int len) { int i = 0; StringBuffer s = new StringBuffer(); while (len >= 3) { i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8) | (b[off + 2] & 0xFF); s.append(b64e[(i >> 18) & 0x3F]); s.append(b64e[(i >> 12) & 0x3F]); s.append(b64e[(i >> 6) & 0x3F]); s.append(b64e[i & 0x3F]); off += 3; len -= 3; } switch (len) { case 2: i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8); s.append(b64e[(i >> 18) & 0x3F]); s.append(b64e[(i >> 12) & 0x3F]); s.append(b64e[(i >> 6) & 0x3F]); s.append('='); break; case 1: i = ((b[off] & 0xFF) << 16); s.append(b64e[(i >> 18) & 0x3F]); s.append(b64e[(i >> 12) & 0x3F]); s.append('='); s.append('='); break; } return s.toString(); } public static String encodeBase64(byte[] b) { return encodeBase64(b, 0, b.length); } private static int b64d(char i) { switch (i) { case 'A': return 0; case 'B': return 1; case 'C': return 2; case 'D': return 3; case 'E': return 4; case 'F': return 5; case 'G': return 6; case 'H': return 7; case 'I': return 8; case 'J': return 9; case 'K': return 10; case 'L': return 11; case 'M': return 12; case 'N': return 13; case 'O': return 14; case 'P': return 15; case 'Q': return 16; case 'R': return 17; case 'S': return 18; case 'T': return 19; case 'U': return 20; case 'V': return 21; case 'W': return 22; case 'X': return 23; case 'Y': return 24; case 'Z': return 25; case 'a': return 26; case 'b': return 27; case 'c': return 28; case 'd': return 29; case 'e': return 30; case 'f': return 31; case 'g': return 32; case 'h': return 33; case 'i': return 34; case 'j': return 35; case 'k': return 36; case 'l': return 37; case 'm': return 38; case 'n': return 39; case 'o': return 40; case 'p': return 41; case 'q': return 42; case 'r': return 43; case 's': return 44; case 't': return 45; case 'u': return 46; case 'v': return 47; case 'w': return 48; case 'x': return 49; case 'y': return 50; case 'z': return 51; case '0': return 52; case '1': return 53; case '2': return 54; case '3': return 55; case '4': return 56; case '5': return 57; case '6': return 58; case '7': return 59; case '8': return 60; case '9': return 61; case '+': return 62; case '/': return 63; default: return -1; } } public static byte[] decodeBase64(String s) { CharacterIterator it = new StringCharacterIterator(s.trim()); ByteArrayOutputStream out = new ByteArrayOutputStream(); int i = 0, j = 0; for (char ch = it.first(); ch != CharacterIterator.DONE && ch != '='; ch = it.next()) { int v = b64d(ch); if (v >= 0) { i = (i << 6) | v; j++; if (j >= 4) { out.write(i >> 16); out.write(i >> 8); out.write(i); i = 0; j = 0; } } } switch (j) { case 3: out.write(i >> 10); out.write(i >> 2); break; case 2: out.write(i >> 4); break; } return out.toByteArray(); } public static String encodeUU(byte[] b, int off, int len) { int i = 0; StringBuffer s = new StringBuffer(); while (len > 45) { s.append('M'); for (int j = 0; j < 45; j += 3) { i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8) | (b[off + 2] & 0xFF); s.append((char) (' ' + ((i >> 18) & 0x3F))); s.append((char) (' ' + ((i >> 12) & 0x3F))); s.append((char) (' ' + ((i >> 6) & 0x3F))); s.append((char) (' ' + (i & 0x3F))); off += 3; len -= 3; } s.append('\n'); } s.append((char) (' ' + len)); while (len >= 3) { i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8) | (b[off + 2] & 0xFF); s.append((char) (' ' + ((i >> 18) & 0x3F))); s.append((char) (' ' + ((i >> 12) & 0x3F))); s.append((char) (' ' + ((i >> 6) & 0x3F))); s.append((char) (' ' + (i & 0x3F))); off += 3; len -= 3; } switch (len) { case 2: i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8); s.append((char) (' ' + ((i >> 18) & 0x3F))); s.append((char) (' ' + ((i >> 12) & 0x3F))); s.append((char) (' ' + ((i >> 6) & 0x3F))); break; case 1: i = ((b[off] & 0xFF) << 16); s.append((char) (' ' + ((i >> 18) & 0x3F))); s.append((char) (' ' + ((i >> 12) & 0x3F))); break; } return s.toString(); } public static String encodeUU(byte[] b) { return encodeUU(b, 0, b.length); } public static byte[] decodeUU(String s) { s = s.replaceAll("\r\n|\r|\n|\u2028|\u2029", "\n").trim(); if (s.startsWith("begin ") && s.endsWith("\nend")) { int o = s.indexOf('\n'); int e = s.length() - 4; s = s.substring(o, e).trim(); } CharacterIterator it = new StringCharacterIterator(s); ByteArrayOutputStream out = new ByteArrayOutputStream(); int i = 0, j = 0; for (char ch = it.first(); ch != CharacterIterator.DONE && ch != '`'; ch = it.next()) { if (ch <= ' ' || ch >= '`') continue; while (true) { int v = (int) (it.next() - ' '); if (v >= 0 && v < 64) { i = (i << 6) | v; j++; if (j >= 4) { out.write(i >> 16); out.write(i >> 8); out.write(i); i = 0; j = 0; } } else { break; } } } switch (j) { case 3: out.write(i >> 10); out.write(i >> 2); break; case 2: out.write(i >> 4); break; } return out.toByteArray(); } private static final char[] xxe = { '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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', }; public static String encodeXX(byte[] b, int off, int len) { int i = 0; StringBuffer s = new StringBuffer(); while (len > 45) { s.append(xxe[45]); for (int j = 0; j < 45; j += 3) { i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8) | (b[off + 2] & 0xFF); s.append(xxe[(i >> 18) & 0x3F]); s.append(xxe[(i >> 12) & 0x3F]); s.append(xxe[(i >> 6) & 0x3F]); s.append(xxe[i & 0x3F]); off += 3; len -= 3; } s.append('\n'); } s.append(xxe[len]); while (len >= 3) { i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8) | (b[off + 2] & 0xFF); s.append(xxe[(i >> 18) & 0x3F]); s.append(xxe[(i >> 12) & 0x3F]); s.append(xxe[(i >> 6) & 0x3F]); s.append(xxe[i & 0x3F]); off += 3; len -= 3; } switch (len) { case 2: i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8); s.append(xxe[(i >> 18) & 0x3F]); s.append(xxe[(i >> 12) & 0x3F]); s.append(xxe[(i >> 6) & 0x3F]); break; case 1: i = ((b[off] & 0xFF) << 16); s.append(xxe[(i >> 18) & 0x3F]); s.append(xxe[(i >> 12) & 0x3F]); break; } return s.toString(); } public static String encodeXX(byte[] b) { return encodeXX(b, 0, b.length); } private static int xxd(char i) { switch (i) { case '+': return 0; case '-': return 1; case '0': return 2; case '1': return 3; case '2': return 4; case '3': return 5; case '4': return 6; case '5': return 7; case '6': return 8; case '7': return 9; case '8': return 10; case '9': return 11; case 'A': return 12; case 'B': return 13; case 'C': return 14; case 'D': return 15; case 'E': return 16; case 'F': return 17; case 'G': return 18; case 'H': return 19; case 'I': return 20; case 'J': return 21; case 'K': return 22; case 'L': return 23; case 'M': return 24; case 'N': return 25; case 'O': return 26; case 'P': return 27; case 'Q': return 28; case 'R': return 29; case 'S': return 30; case 'T': return 31; case 'U': return 32; case 'V': return 33; case 'W': return 34; case 'X': return 35; case 'Y': return 36; case 'Z': return 37; case 'a': return 38; case 'b': return 39; case 'c': return 40; case 'd': return 41; case 'e': return 42; case 'f': return 43; case 'g': return 44; case 'h': return 45; case 'i': return 46; case 'j': return 47; case 'k': return 48; case 'l': return 49; case 'm': return 50; case 'n': return 51; case 'o': return 52; case 'p': return 53; case 'q': return 54; case 'r': return 55; case 's': return 56; case 't': return 57; case 'u': return 58; case 'v': return 59; case 'w': return 60; case 'x': return 61; case 'y': return 62; case 'z': return 63; default: return -1; } } public static byte[] decodeXX(String s) { s = s.replaceAll("\r\n|\r|\n|\u2028|\u2029", "\n").trim(); if (s.startsWith("begin ") && s.endsWith("\nend")) { int o = s.indexOf('\n'); int e = s.length() - 4; s = s.substring(o, e).trim(); } CharacterIterator it = new StringCharacterIterator(s); ByteArrayOutputStream out = new ByteArrayOutputStream(); int i = 0, j = 0; for (char ch = it.first(); ch != CharacterIterator.DONE && ch != '+'; ch = it.next()) { if (xxd(ch) < 0) continue; while (true) { int v = xxd(it.next()); if (v >= 0) { i = (i << 6) | v; j++; if (j >= 4) { out.write(i >> 16); out.write(i >> 8); out.write(i); i = 0; j = 0; } } else { break; } } } switch (j) { case 3: out.write(i >> 10); out.write(i >> 2); break; case 2: out.write(i >> 4); break; } return out.toByteArray(); } private static final char[] hqxe = { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '0', '1', '2', '3', '4', '5', '6', '8', '9', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', '[', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'j', 'k', 'l', 'm', 'p', 'q', 'r', }; public static String encodeBinHex(byte[] b, int off, int len) { // phase 1 - RLE ByteArrayOutputStream iout = new ByteArrayOutputStream(); while (len > 0) { byte v = b[off++]; int r = 1; len--; while (len > 0 && b[off] == v && r < 255) { off++; r++; len--; } if (r > 2) { if (v == (byte) 0x90) { iout.write(0x90); iout.write(0); } else { iout.write(v); } iout.write(0x90); iout.write(r); } else while (r-- > 0) { if (v == (byte) 0x90) { iout.write(0x90); iout.write(0); } else { iout.write(v); } } } b = iout.toByteArray(); off = 0; len = b.length; // phase 2 - base64 encoding int i = 0; StringBuffer s = new StringBuffer(); s.append(':'); while (len >= 3) { i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8) | (b[off + 2] & 0xFF); s.append(hqxe[(i >> 18) & 0x3F]); s.append(hqxe[(i >> 12) & 0x3F]); s.append(hqxe[(i >> 6) & 0x3F]); s.append(hqxe[i & 0x3F]); off += 3; len -= 3; } switch (len) { case 2: i = ((b[off] & 0xFF) << 16) | ((b[off + 1] & 0xFF) << 8); s.append(hqxe[(i >> 18) & 0x3F]); s.append(hqxe[(i >> 12) & 0x3F]); s.append(hqxe[(i >> 6) & 0x3F]); break; case 1: i = ((b[off] & 0xFF) << 16); s.append(hqxe[(i >> 18) & 0x3F]); s.append(hqxe[(i >> 12) & 0x3F]); break; } s.append(':'); return s.toString(); } public static String encodeBinHex(byte[] b) { return encodeBinHex(b, 0, b.length); } private static int hqxd(char i) { switch (i) { case '!': return 0; case '"': return 1; case '#': return 2; case '$': return 3; case '%': return 4; case '&': return 5; case '\'': return 6; case '(': return 7; case ')': return 8; case '*': return 9; case '+': return 10; case ',': return 11; case '-': return 12; case '0': return 13; case '1': return 14; case '2': return 15; case '3': return 16; case '4': return 17; case '5': return 18; case '6': return 19; case '8': return 20; case '9': return 21; case '@': return 22; case 'A': return 23; case 'B': return 24; case 'C': return 25; case 'D': return 26; case 'E': return 27; case 'F': return 28; case 'G': return 29; case 'H': return 30; case 'I': return 31; case 'J': return 32; case 'K': return 33; case 'L': return 34; case 'M': return 35; case 'N': return 36; case 'P': return 37; case 'Q': return 38; case 'R': return 39; case 'S': return 40; case 'T': return 41; case 'U': return 42; case 'V': return 43; case 'X': return 44; case 'Y': return 45; case 'Z': return 46; case '[': return 47; case '`': return 48; case 'a': return 49; case 'b': return 50; case 'c': return 51; case 'd': return 52; case 'e': return 53; case 'f': return 54; case 'h': return 55; case 'i': return 56; case 'j': return 57; case 'k': return 58; case 'l': return 59; case 'm': return 60; case 'p': return 61; case 'q': return 62; case 'r': return 63; default: return -1; } } public static byte[] decodeBinHex(String s) { // phase 1 - base64 encoding CharacterIterator it = new StringCharacterIterator(s.trim()); ByteArrayOutputStream iout = new ByteArrayOutputStream(); int i = 0, j = 0; char ch = it.first(); if (ch == ':') ch = it.next(); while (ch != CharacterIterator.DONE && ch != ':') { int v = hqxd(ch); if (v >= 0) { i = (i << 6) | v; j++; if (j >= 4) { iout.write(i >> 16); iout.write(i >> 8); iout.write(i); i = 0; j = 0; } } ch = it.next(); } switch (j) { case 3: iout.write(i >> 10); iout.write(i >> 2); break; case 2: iout.write(i >> 4); break; } byte[] b = iout.toByteArray(); // phase 2 - RLE int off = 0; ByteArrayOutputStream out = new ByteArrayOutputStream(); byte last = 0; while (off < b.length) { byte v = b[off++]; if (v == (byte) 0x90 && off < b.length) { int r = b[off++] & 0xFF; if (r == 0) { out.write(last = (byte) 0x90); } else { r--; while (r-- > 0) { out.write(last); } } } else { out.write(last = v); } } return out.toByteArray(); } public static String encodeASCII85(byte[] b, int off, int len) { long i = 0; StringBuffer s = new StringBuffer(); s.append("<~"); while (len >= 4) { i = ((b[off] & 0xFFL) << 24L) | ((b[off + 1] & 0xFFL) << 16L) | ((b[off + 2] & 0xFFL) << 8L) | (b[off + 3] & 0xFFL); if (i == 0) { s.append('z'); } else { s.append((char) ('!' + ((i / 52200625) % 85))); s.append((char) ('!' + ((i / 614125) % 85))); s.append((char) ('!' + ((i / 7225) % 85))); s.append((char) ('!' + ((i / 85) % 85))); s.append((char) ('!' + (i % 85))); } off += 4; len -= 4; } switch (len) { case 3: i = ((b[off] & 0xFFL) << 24L) | ((b[off + 1] & 0xFFL) << 16L) | ((b[off + 2] & 0xFFL) << 8L); s.append((char) ('!' + ((i / 52200625) % 85))); s.append((char) ('!' + ((i / 614125) % 85))); s.append((char) ('!' + ((i / 7225) % 85))); s.append((char) ('!' + ((i / 85) % 85))); break; case 2: i = ((b[off] & 0xFFL) << 24L) | ((b[off + 1] & 0xFFL) << 16L); s.append((char) ('!' + ((i / 52200625) % 85))); s.append((char) ('!' + ((i / 614125) % 85))); s.append((char) ('!' + ((i / 7225) % 85))); break; case 1: i = ((b[off] & 0xFFL) << 24L); s.append((char) ('!' + ((i / 52200625) % 85))); s.append((char) ('!' + ((i / 614125) % 85))); break; } s.append("~>"); return s.toString(); } public static String encodeASCII85(byte[] b) { return encodeASCII85(b, 0, b.length); } public static byte[] decodeASCII85(String s) { s = s.trim(); if (s.startsWith("<~") && s.endsWith("~>")) { s = s.substring(2, s.length() - 2).trim(); } CharacterIterator it = new StringCharacterIterator(s); ByteArrayOutputStream out = new ByteArrayOutputStream(); long i = 0; int j = 0; for (char ch = it.first(); ch != CharacterIterator.DONE && ch != '~'; ch = it.next()) { if (ch == 'z' && j == 0) { out.write(0); out.write(0); out.write(0); out.write(0); } else if (ch == 'y' && j == 0) { out.write(' '); out.write(' '); out.write(' '); out.write(' '); } else if (ch == 'x' && j == 0) { out.write(-1); out.write(-1); out.write(-1); out.write(-1); } else if (ch >= '!' && ch <= 'u') { i = i * 85L + (long) (ch - '!'); j++; if (j >= 5) { out.write((int) (i >> 24L)); out.write((int) (i >> 16L)); out.write((int) (i >> 8L)); out.write((int) i); i = 0; j = 0; } } } switch (j) { case 4: i = i * 85L + 84L; out.write((int) (i >> 24L)); out.write((int) (i >> 16L)); out.write((int) (i >> 8L)); break; case 3: i = i * 85L + 84L; i = i * 85L + 84L; out.write((int) (i >> 24L)); out.write((int) (i >> 16L)); break; case 2: i = i * 85L + 84L; i = i * 85L + 84L; i = i * 85L + 84L; out.write((int) (i >> 24L)); break; } return out.toByteArray(); } private static final char[] k85e = { '!', '#', '$', '%', '&', '(', ')', '+', ',', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '=', '@', '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', '{', '}', '~', }; public static String encodeKreative85(byte[] b, int off, int len) { long i = 0; StringBuffer s = new StringBuffer(); while (len >= 4) { i = ((b[off] & 0xFFL) << 24L) | ((b[off + 1] & 0xFFL) << 16L) | ((b[off + 2] & 0xFFL) << 8L) | (b[off + 3] & 0xFFL); s.append(k85e[(int) ((i / 52200625) % 85)]); s.append(k85e[(int) ((i / 614125) % 85)]); s.append(k85e[(int) ((i / 7225) % 85)]); s.append(k85e[(int) ((i / 85) % 85)]); s.append(k85e[(int) (i % 85)]); off += 4; len -= 4; } switch (len) { case 3: i = ((b[off] & 0xFFL) << 24L) | ((b[off + 1] & 0xFFL) << 16L) | ((b[off + 2] & 0xFFL) << 8L); s.append(k85e[(int) ((i / 52200625) % 85)]); s.append(k85e[(int) ((i / 614125) % 85)]); s.append(k85e[(int) ((i / 7225) % 85)]); s.append(k85e[(int) ((i / 85) % 85)]); break; case 2: i = ((b[off] & 0xFFL) << 24L) | ((b[off + 1] & 0xFFL) << 16L); s.append(k85e[(int) ((i / 52200625) % 85)]); s.append(k85e[(int) ((i / 614125) % 85)]); s.append(k85e[(int) ((i / 7225) % 85)]); break; case 1: i = ((b[off] & 0xFFL) << 24L); s.append(k85e[(int) ((i / 52200625) % 85)]); s.append(k85e[(int) ((i / 614125) % 85)]); break; } return s.toString(); } public static String encodeKreative85(byte[] b) { return encodeKreative85(b, 0, b.length); } public static String encodeLegacy85(byte[] b, int off, int len) { long i = 0; StringBuffer s = new StringBuffer(); s.append('<'); s.append(k85e[(int) ((long) len % 85L)]); s.append(k85e[(int) (((long) len / 85L) % 85L)]); s.append(k85e[(int) (((long) len / 7225L) % 85L)]); s.append(k85e[(int) (((long) len / 614125L) % 85L)]); s.append(k85e[(int) (((long) len / 52200625L) % 85L)]); s.append('>'); while (len >= 4) { i = ((b[off + 3] & 0xFFL) << 24L) | ((b[off + 2] & 0xFFL) << 16L) | ((b[off + 1] & 0xFFL) << 8L) | (b[off] & 0xFFL); s.append(k85e[(int) (i % 85L)]); s.append(k85e[(int) ((i / 85L) % 85L)]); s.append(k85e[(int) ((i / 7225L) % 85L)]); s.append(k85e[(int) ((i / 614125L) % 85L)]); s.append(k85e[(int) ((i / 52200625L) % 85L)]); off += 4; len -= 4; } if (len > 0) { switch (len) { case 3: i = ((b[off + 2] & 0xFFL) << 16L) | ((b[off + 1] & 0xFFL) << 8L) | (b[off] & 0xFFL); break; case 2: i = ((b[off + 1] & 0xFFL) << 8L) | (b[off] & 0xFFL); break; case 1: i = (b[off] & 0xFFL); break; } s.append(k85e[(int) (i % 85L)]); s.append(k85e[(int) ((i / 85L) % 85L)]); s.append(k85e[(int) ((i / 7225L) % 85L)]); s.append(k85e[(int) ((i / 614125L) % 85L)]); s.append(k85e[(int) ((i / 52200625L) % 85L)]); } return s.toString(); } public static String encodeLegacy85(byte[] b) { return encodeLegacy85(b, 0, b.length); } private static int k85d(char i) { switch (i) { case '!': return 0; case '#': return 1; case '$': return 2; case '%': return 3; case '&': return 4; case '(': return 5; case ')': return 6; case '+': return 7; case ',': return 8; case '-': return 9; case '.': return 10; case '0': return 11; case '1': return 12; case '2': return 13; case '3': return 14; case '4': return 15; case '5': return 16; case '6': return 17; case '7': return 18; case '8': return 19; case '9': return 20; case ':': return 21; case ';': return 22; case '=': return 23; case '@': return 24; case 'A': return 25; case 'B': return 26; case 'C': return 27; case 'D': return 28; case 'E': return 29; case 'F': return 30; case 'G': return 31; case 'H': return 32; case 'I': return 33; case 'J': return 34; case 'K': return 35; case 'L': return 36; case 'M': return 37; case 'N': return 38; case 'O': return 39; case 'P': return 40; case 'Q': return 41; case 'R': return 42; case 'S': return 43; case 'T': return 44; case 'U': return 45; case 'V': return 46; case 'W': return 47; case 'X': return 48; case 'Y': return 49; case 'Z': return 50; case '[': return 51; case ']': return 52; case '^': return 53; case '_': return 54; case '`': return 55; case 'a': return 56; case 'b': return 57; case 'c': return 58; case 'd': return 59; case 'e': return 60; case 'f': return 61; case 'g': return 62; case 'h': return 63; case 'i': return 64; case 'j': return 65; case 'k': return 66; case 'l': return 67; case 'm': return 68; case 'n': return 69; case 'o': return 70; case 'p': return 71; case 'q': return 72; case 'r': return 73; case 's': return 74; case 't': return 75; case 'u': return 76; case 'v': return 77; case 'w': return 78; case 'x': return 79; case 'y': return 80; case 'z': return 81; case '{': return 82; case '}': return 83; case '~': return 84; default: return -1; } } public static byte[] decodeKreative85(String s) { CharacterIterator it = new StringCharacterIterator(s.trim()); ByteArrayOutputStream out = new ByteArrayOutputStream(); long i = 0; int j = 0; for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) { int v = k85d(ch); if (v >= 0) { i = i * 85L + v; j++; if (j >= 5) { out.write((int) (i >> 24L)); out.write((int) (i >> 16L)); out.write((int) (i >> 8L)); out.write((int) i); i = 0; j = 0; } } } switch (j) { case 4: i = i * 85L + 84L; out.write((int) (i >> 24L)); out.write((int) (i >> 16L)); out.write((int) (i >> 8L)); break; case 3: i = i * 85L + 84L; i = i * 85L + 84L; out.write((int) (i >> 24L)); out.write((int) (i >> 16L)); break; case 2: i = i * 85L + 84L; i = i * 85L + 84L; i = i * 85L + 84L; out.write((int) (i >> 24L)); break; } return out.toByteArray(); } public static byte[] decodeLegacy85(String s) { int targetLength = -1; s = s.trim(); if (s.length() >= 7 && s.charAt(0) == '<' && s.charAt(6) == '>') { targetLength = k85d(s.charAt(1)) + k85d(s.charAt(2)) * 85 + k85d(s.charAt(3)) * 7225 + k85d(s.charAt(4)) * 614125 + k85d(s.charAt(5)) * 52200625; s = s.substring(7).trim(); } CharacterIterator it = new StringCharacterIterator(s); ByteArrayOutputStream out = new ByteArrayOutputStream(); long i = 0; int j = 0; long k = 1; for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) { int v = k85d(ch); if (v >= 0) { i += v * k; j++; k *= 85; if (j >= 5) { out.write((int) i); out.write((int) (i >> 8L)); out.write((int) (i >> 16L)); out.write((int) (i >> 24L)); i = 0; j = 0; k = 1; } } } if (j > 0) { out.write((int) i); out.write((int) (i >> 8L)); out.write((int) (i >> 16L)); out.write((int) (i >> 24L)); } if (targetLength >= 0) { byte[] b = out.toByteArray(); byte[] bt = new byte[targetLength]; for (int x = 0; x < targetLength && x < b.length; x++) { bt[x] = b[x]; } return bt; } else { return out.toByteArray(); } } public static void main(String[] args) throws IOException { boolean decode = false; int mode = 0; for (String arg : args) { if (arg.equals("-e")) { decode = false; } else if (arg.equals("-d")) { decode = true; } else if (arg.equals("-b64")) { mode = 0; } else if (arg.equals("-hqx")) { mode = 1; } else if (arg.equals("-a85")) { mode = 2; } else if (arg.equals("-l85")) { mode = 3; } else if (arg.equals("-k85")) { mode = 4; } else if (arg.equals("-uue")) { mode = 5; } else if (arg.equals("-xxe")) { mode = 6; } else if (arg.equals("--")) { ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buf = new byte[1048576]; int len = 0; while ((len = System.in.read(buf)) >= 0) { out.write(buf, 0, len); } out.close(); if (decode) { switch (mode) { case 0: System.out.println(new String(decodeBase64(out.toString()))); break; case 1: System.out.println(new String(decodeBinHex(out.toString()))); break; case 2: System.out.println(new String(decodeASCII85(out.toString()))); break; case 3: System.out.println(new String(decodeLegacy85(out.toString()))); break; case 4: System.out.println(new String(decodeKreative85(out.toString()))); break; case 5: System.out.println(new String(decodeUU(out.toString()))); break; case 6: System.out.println(new String(decodeXX(out.toString()))); break; } } else { switch (mode) { case 0: System.out.println(encodeBase64(out.toByteArray())); break; case 1: System.out.println(encodeBinHex(out.toByteArray())); break; case 2: System.out.println(encodeASCII85(out.toByteArray())); break; case 3: System.out.println(encodeLegacy85(out.toByteArray())); break; case 4: System.out.println(encodeKreative85(out.toByteArray())); break; case 5: System.out.println(encodeUU(out.toByteArray())); break; case 6: System.out.println(encodeXX(out.toByteArray())); break; } } } else if (decode) { switch (mode) { case 0: System.out.println(new String(decodeBase64(arg))); break; case 1: System.out.println(new String(decodeBinHex(arg))); break; case 2: System.out.println(new String(decodeASCII85(arg))); break; case 3: System.out.println(new String(decodeLegacy85(arg))); break; case 4: System.out.println(new String(decodeKreative85(arg))); break; case 5: System.out.println(new String(decodeUU(arg))); break; case 6: System.out.println(new String(decodeXX(arg))); break; } } else { switch (mode) { case 0: System.out.println(encodeBase64(arg.getBytes())); break; case 1: System.out.println(encodeBinHex(arg.getBytes())); break; case 2: System.out.println(encodeASCII85(arg.getBytes())); break; case 3: System.out.println(encodeLegacy85(arg.getBytes())); break; case 4: System.out.println(encodeKreative85(arg.getBytes())); break; case 5: System.out.println(encodeUU(arg.getBytes())); break; case 6: System.out.println(encodeXX(arg.getBytes())); break; } } } } }