ImportStream.java Source code

Java tutorial

Introduction

Here is the source code for ImportStream.java

Source

/*
 * ImportStream.java Created Sep 9, 2010 by Andrew Butler, PSL
 */
//package prisms.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

/** Wraps a stream that has been exported to import the data in readable form */
public class ImportStream extends java.io.InputStream {
    private java.io.InputStream theInput;

    /**
     * Wraps a stream with an import stream
     * 
     * @param wrap The exported stream to wrap
     * @throws IOException If an error occurs wrapping the stream
     */
    public ImportStream(java.io.InputStream wrap) throws IOException {
        java.util.zip.ZipInputStream zis;
        zis = new java.util.zip.ZipInputStream(ObfuscatingStream.unobfuscate(wrap));
        zis.getNextEntry();
        theInput = zis;
    }

    @Override
    public int read() throws IOException {
        return theInput.read();
    }

    @Override
    public int read(byte[] b) throws IOException {
        return theInput.read(b);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        return theInput.read(b, off, len);
    }

    @Override
    public long skip(long n) throws IOException {
        return theInput.skip(n);
    }

    @Override
    public int available() throws IOException {
        return theInput.available();
    }

    @Override
    public boolean markSupported() {
        return theInput.markSupported();
    }

    @Override
    public synchronized void mark(int readlimit) {
        theInput.mark(readlimit);
    }

    @Override
    public synchronized void reset() throws IOException {
        theInput.reset();
    }

    @Override
    public void close() throws IOException {
        theInput.close();
    }

}

/**
 * A utility class that allows for easy simple obfuscation of streamed data
 */
class ObfuscatingStream {
    private static final char[] HEX_CHARS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
            'C', 'D', 'E', 'F' };

    /**
     * A class that obfuscates data as it is written to a binary stream
     */
    public static class ObfuscatingOutputStream extends OutputStream {
        private OutputStream theOS;

        private int theWarp;

        private int theCount;

        ObfuscatingOutputStream(OutputStream os) {
            theOS = os;
            theWarp = -1;
        }

        /**
         * @see java.io.OutputStream#write(int)
         */
        @Override
        public void write(int b) throws IOException {
            if (theWarp < 0) {
                theWarp = (int) (Math.random() * 8);
                theOS.write(theWarp);
            }
            int shift = (theWarp + theCount) % 8;
            theCount++;
            int toWrite = b & 0xff;
            toWrite = ((toWrite >> shift) | (toWrite << (8 - shift))) & 0xff;
            theOS.write(toWrite);
        }
    }

    /**
     * A class the unobfuscates data that was obfuscated by an {@link ObfuscatingOutputStream} as it
     * is read from an input stream
     */
    public static class UnobfuscatingInputStream extends InputStream {
        private InputStream theIS;

        private int theWarp;

        private int theCount;

        UnobfuscatingInputStream(InputStream is) {
            theIS = is;
            theWarp = -1;
        }

        /**
         * @see java.io.InputStream#read()
         */
        @Override
        public int read() throws IOException {
            if (theWarp < 0)
                theWarp = theIS.read();
            int read = theIS.read();
            if (read < 0)
                return read;
            int shift = (theWarp + theCount) % 8;
            theCount++;
            int ret = read & 0xff;
            ret = ((ret << shift) | (ret >> (8 - shift))) & 0xff;
            return ret;
        }
    }

    /**
     * Obfuscates an output stream
     * 
     * @param os The binary output stream for this utility to write obfuscated data to
     * @return The output stream for the calling method to write unobfuscated data
     */
    public static OutputStream obfuscate(OutputStream os) {
        return new ObfuscatingOutputStream(os);
    }

    /**
     * Unobfuscates an input stream
     * 
     * @param is The binary input stream for this utililty to read obfuscated data from
     * @return The input stream for the calling method to read the unobfuscated data from
     */
    public static InputStream unobfuscate(InputStream is) {
        return new UnobfuscatingInputStream(is);
    }

    /**
     * Obfuscates or unobfuscates the second command-line argument, depending on whether the first
     * argument starts with "o" or "u"
     * 
     * @param args Command-line arguments
     * @throws IOException If an error occurs obfuscating or unobfuscating
     */
    public static void main(String[] args) throws IOException {
        InputStream input = new ByteArrayInputStream(args[1].getBytes());
        StringBuilder toPrint = new StringBuilder();
        if (args[0].startsWith("o")) {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            OutputStream out = obfuscate(bytes);
            int read = input.read();
            while (read >= 0) {
                out.write(read);
                read = input.read();
            }
            byte[] receiptBytes = bytes.toByteArray();
            for (int b = 0; b < receiptBytes.length; b++) {
                int chr = (receiptBytes[b] + 256) % 256;
                toPrint.append(HEX_CHARS[chr >>> 4]);
                toPrint.append(HEX_CHARS[chr & 0xf]);
            }
        } else if (args[0].startsWith("u")) {
            input = unobfuscate(input);
            InputStreamReader reader = new InputStreamReader(input);

            int read = reader.read();
            while (read >= 0) {
                toPrint.append((char) read);
                read = reader.read();
            }
        } else
            throw new IllegalArgumentException("First argument must start with o or u");
        System.out.println(toPrint.toString());
    }
}