Mega Code Archive

 
Categories / Java / File Input Output
 

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());   } }