ObfuscatingStream.java Source code

Java tutorial

Introduction

Here is the source code for ObfuscatingStream.java

Source

/**
 * ObfuscatingStream.java Created Apr 22, 2009 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;

/**
 * A utility class that allows for easy simple obfuscation of streamed data
 */
public 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());
    }
}