Java解压密码的zip文件
2015-01-26 13:53
579 查看
import java.io.IOException; import java.io.InputStream; 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 } }
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; // usage: java Main [filename] [password] public class Main { public static void main(String[] args) throws IOException { // password-protected zip file I need to read FileInputStream fis = new FileInputStream(args[0]); // wrap it in the decrypt stream ZipDecryptInputStream zdis = new ZipDecryptInputStream(fis, args[1]); // 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) { FileOutputStream fos = new FileOutputStream(ze.getName()); int b; while ((b = zis.read()) != -1) { fos.write(b); } fos.close(); zis.closeEntry(); } zis.close(); } }
refer:http://blog.alutam.com/2009/10/31/reading-password-protected-zip-files-in-java/
相关文章推荐
- Java 解压和压缩密码zip文件
- java解压带密码的zip文件
- Java解压和压缩带密码的zip文件(转…
- AS3 和 Java 密码解压zip文件
- Java解压和压缩带密码的zip文件
- java解压缩zip文件,java创建zip文件,java压缩文件,java解压文件,用到ant.jar解决汉字乱码
- java解压缩zip文件,java创建zip文件,java压缩文件,java解压文件,用到ant.jar解决汉字乱码
- JAVA使用7-zip解压缩带密码的Zip文件(非Proccess方法)
- java-在Java中操作Zip文件,压缩/解压
- java 压缩解压zip文件--使用ant支持中文
- Java解压带密码的Rar压缩文件
- Java压缩解压zip文件的中文文件名在Windows和Linux环境下乱码问题的解决方案
- java解压zip文件,处理文件名不能为中文
- 使用Java解压ZIP文件
- 通过Java生成加密压缩文件(支持AES压缩和解压zip文件)
- Java无需解压直接读取Zip文件和文件内容
- Java无需解压直接读取Zip文件和文件内容
- java-在Java中操作Zip文件,压缩/解压
- java解压缩zip文件,java创建zip文件,java压缩文件,java解压文件,用到ant.jar解决汉字乱码
- java解压缩zip文件,java创建zip文件,java压缩文件,java解压文件,用到ant.jar解决汉字乱码