Wraps a stream that has been exported to import the data in readable form
/*
* 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());
}
}
Related examples in the same category