java代码实现加密压缩文件解压

来源:互联网 发布:淘宝代理商加盟可靠吗 编辑:程序博客网 时间:2024/06/08 13:34
package com.dashu.basicinfo.zip;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.zip.ZipEntry;import java.util.zip.ZipInputStream;public class ZipDecryptInputStream extends InputStream {   private static final int[] CRC_TABLE = new int[256];   // compute the table   // (could also have it pre-computed - see http://snippets.dzone.com/tag/crc32)   static {       for (int i = 0; i < 256; i++) {           int r = i;           for (int j = 0; j < 8; j++) {               if ((r & 1) == 1) {                   r = (r >>> 1) ^ 0xedb88320;               } else {                   r >>>= 1;               }           }           CRC_TABLE[i] = r;       }   }   private static final int DECRYPT_HEADER_SIZE = 12;   private static final int[] LFH_SIGNATURE = {0x50, 0x4b, 0x03, 0x04};   private final InputStream delegate;   private final String password;   private final int keys[] = new int[3];   private State state = State.SIGNATURE;   private int skipBytes;   private int compressedSize;   private int value;   private int valuePos;   private int valueInc;   public ZipDecryptInputStream(InputStream stream, String password) {       this.delegate = stream;       this.password = password;   }   @Override   public int read() throws IOException {       int result = delegate.read();       if (skipBytes == 0) {           switch (state) {               case SIGNATURE:                   if (result != LFH_SIGNATURE[valuePos]) {                       state = State.TAIL;                   } else {                       valuePos++;                       if (valuePos >= LFH_SIGNATURE.length) {                           skipBytes = 2;                           state = State.FLAGS;                       }                   }                   break;               case FLAGS:                   if ((result & 1) == 0) {                       throw new IllegalStateException("ZIP not password protected.");                   }                   if ((result & 64) == 64) {                       throw new IllegalStateException("Strong encryption used.");                   }                   if ((result & 8) == 8) {                       throw new IllegalStateException("Unsupported ZIP format.");                   }                   result -= 1;                   compressedSize = 0;                   valuePos = 0;                   valueInc = DECRYPT_HEADER_SIZE;                   state = State.COMPRESSED_SIZE;                   skipBytes = 11;                   break;               case COMPRESSED_SIZE:                   compressedSize += result << (8 * valuePos);                   result -= valueInc;                   if (result < 0) {                       valueInc = 1;                       result += 256;                   } else {                       valueInc = 0;                   }                   valuePos++;                   if (valuePos > 3) {                       valuePos = 0;                       value = 0;                       state = State.FN_LENGTH;                       skipBytes = 4;                   }                   break;               case FN_LENGTH:               case EF_LENGTH:                   value += result << 8 * valuePos;                   if (valuePos == 1) {                       valuePos = 0;                       if (state == State.FN_LENGTH) {                           state = State.EF_LENGTH;                       } else {                           state = State.HEADER;                           skipBytes = value;                       }                   } else {                       valuePos = 1;                   }                   break;               case HEADER:                   initKeys(password);                   for (int i = 0; i < DECRYPT_HEADER_SIZE; i++) {                       updateKeys((byte) (result ^ decryptByte()));                       result = delegate.read();                   }                   compressedSize -= DECRYPT_HEADER_SIZE;                   state = State.DATA;                   // intentionally no break               case DATA:                   result = (result ^ decryptByte()) & 0xff;                   updateKeys((byte) result);                   compressedSize--;                   if (compressedSize == 0) {                       valuePos = 0;                       state = State.SIGNATURE;                   }                   break;               case TAIL:                   // do nothing           }       } else {           skipBytes--;       }       return result;   }   @Override   public void close() throws IOException {       delegate.close();       super.close();   }   private void initKeys(String password) {       keys[0] = 305419896;       keys[1] = 591751049;       keys[2] = 878082192;       for (int i = 0; i < password.length(); i++) {           updateKeys((byte) (password.charAt(i) & 0xff));       }   }   private void updateKeys(byte charAt) {       keys[0] = crc32(keys[0], charAt);       keys[1] += keys[0] & 0xff;       keys[1] = keys[1] * 134775813 + 1;       keys[2] = crc32(keys[2], (byte) (keys[1] >> 24));   }   private byte decryptByte() {       int temp = keys[2] | 2;       return (byte) ((temp * (temp ^ 1)) >>> 8);   }   private int crc32(int oldCrc, byte charAt) {       return ((oldCrc >>> 8) ^ CRC_TABLE[(oldCrc ^ charAt) & 0xff]);   }   private static enum State {       SIGNATURE, FLAGS, COMPRESSED_SIZE, FN_LENGTH, EF_LENGTH, HEADER, DATA, TAIL   }      public static void main(String[] args) throws Exception {  // password-protected zip file I need to read      FileInputStream fis = new FileInputStream("d:/123/one.zip");      // wrap it in the decrypt stream      ZipDecryptInputStream zdis = new ZipDecryptInputStream(fis, "1234567");      // wrap the decrypt stream by the ZIP input stream      ZipInputStream zis = new ZipInputStream(zdis);      // read all the zip entries and save them as files      ZipEntry ze;      while ((ze = zis.getNextEntry()) != null) {      File f = new File("d:/123/"+ze.getName());          FileOutputStream fos = new FileOutputStream(f);          int b;          try {while ((b = zis.read()) != -1) {    fos.write(b);}} catch (Exception e) {fos.close();f.delete(); zis.closeEntry(); break;}          fos.close();          zis.closeEntry();      }      zis.close();}}

0 0