Java方法进行解压/生成有密码保护的压缩文件(zip格式)

以下是源代码,使用说明包含在文件头部的注释中。

1.
  1  import  java.io.IOException;
  2  import  java.io.InputStream;
  3 
  4  import   static ZipUtil. * ;
  5 
  6  /**
  7   * Input stream converting a password-protected zip to an unprotected zip.
  8   *
  9   * <h3>Example usage:</h3>
 10   * <p>Reading a password-protected zip from file:</p>
 11   * <pre>
 12   *  ZipDecryptInputStream zdis = new ZipDecryptInputStream(new FileInputStream(fileName), password);
 13   *  ZipInputStream zis = new ZipInputStream(zdis);
 14   *   read the zip file from zis - the standard JDK ZipInputStream 
 15   * </pre>
 16   * <p>Converting a password-protected zip file to an unprotected zip file:</p>
 17   * <pre>
 18   *  ZipDecryptInputStream src = new ZipDecryptInputStream(new FileInputStream(srcFile), password);
 19   *  FileOutputStream dest = new FileOutputStream(destFile);
 20   *
 21   *  // should wrap with try-catch-finally, do the close in finally
 22   *  int b;
 23   *  while ((b = src.read()) > -1) {
 24   *      dest.write(b);
 25   *  }
 26   *
 27   *  src.close();
 28   *  dest.close();
 29   * </pre>
 30   *
 31   *  @author  Martin Matula (martin at alutam.com)
 32    */
 33  public   class  ZipDecryptInputStream  extends  InputStream {
 34       private   final  InputStream delegate;
 35       private   final   int  keys[]  =   new   int [ 3 ];
 36       private   final   int  pwdKeys[]  =   new   int [ 3 ];
 37
 38       private  State state  =  State.SIGNATURE;
 39       private   boolean  isEncrypted;
 40       private  Section section;
 41       private   int  skipBytes;
 42       private   int  compressedSize;
 43       private   int  crc;
 44 
 45       /**
 46       * Creates a new instance of the stream.
 47       *
 48       *  @param  stream Input stream serving the password-protected zip file to be decrypted.
 49       *  @param  password Password to be used to decrypt the password-protected zip file.
 50        */
 51       public  ZipDecryptInputStream(InputStream stream, String password) {
 52           this (stream, password.toCharArray());
 53      }
 54 
 55       /**
 56       * Safer constructor. Takes password as a char array that can be nulled right after
 57       * calling this constructor instead of a string that may be visible on the heap for
 58       * the duration of application run time.
 59       *
 60       *  @param  stream Input stream serving the password-protected zip file.
 61       *  @param  password Password to use for decrypting the zip file.
 62        */
 63       public  ZipDecryptInputStream(InputStream stream,  char [] password) {
 64           this .delegate  =  stream;
 65          pwdKeys[ 0 =   305419896 ;
 66          pwdKeys[ 1 =   591751049 ;
 67          pwdKeys[ 2 =   878082192 ;
 68           for  ( int  i  =   0 ; i  <  password.length; i ++ ) {
 69              ZipUtil.updateKeys(( byte ) (password[i]  &   0xff ), pwdKeys);
 70          }
 71      }
 72 
 73      @Override
 74       public   int  read()  throws  IOException {
 75           int  result  =  delegateRead();
 76           if  (skipBytes  ==   0 ) {
 77               switch  (state) {
 78                   case  SIGNATURE:
 79                       if  ( ! peekAheadEquals(LFH_SIGNATURE)) {
 80                          state  =  State.TAIL;
 81                      }  else  {
 82                          section  =  Section.FILE_HEADER;
 83                          skipBytes  =   5 ;
 84                          state  =  State.FLAGS;
 85                      }
 86                       break ;
 87                   case  FLAGS:
 88                      isEncrypted  =  (result  &   1 !=   0 ;
 89                       if  ((result  &   64 ==   64 ) {
 90                           throw   new  IllegalStateException( " Strong encryption used. " );
 91                      }
 92                       if  ((result  &   8 ==   8 ) {
 93                          compressedSize  =   - 1 ;
 94                          state  =  State.FN_LENGTH;
 95                          skipBytes  =   19 ;
 96                      }  else  {
 97                          state  =  State.CRC;
 98                          skipBytes  =   10 ;
 99                      }
100                       if  (isEncrypted) {
101                          result  -=   1 ;
102                      }
103                       break ;
104                   case  CRC:
105                      crc  =  result;
106                      state  =  State.COMPRESSED_SIZE;
107                       break ;
108                   case  COMPRESSED_SIZE:
109                       int [] values  =   new   int [ 4 ];
110                      peekAhead(values);
111                      compressedSize  =   0 ;
112                       int  valueInc  =  isEncrypted  ?  DECRYPT_HEADER_SIZE :  0 ;
113                       for  ( int  i  =   0 ; i  <   4 ; i ++ ) {
114                          compressedSize  +=  values[i]  <<  ( 8   *  i);
115                          values[i]  -=  valueInc;
116                           if  (values[i]  <   0 ) {
117                              valueInc  =   1 ;
118                              values[i]  +=   256 ;
119                          }  else  {
120                              valueInc  =   0 ;
121                          }
122                      }
123                      overrideBuffer(values);
124                      result  =  values[ 0 ];
125                       if  (section  ==  Section.DATA_DESCRIPTOR) {
126                          state  =  State.SIGNATURE;
127                      }  else  {
128                          state  =  State.FN_LENGTH;
129                      }
130                      skipBytes  =   7 ;
131                       break ;
132                   case  FN_LENGTH:
133                      values  =   new   int [ 4 ];
134                      peekAhead(values);
135                      skipBytes  =   3   +  values[ 0 +  values[ 2 +  (values[ 1 +  values[ 3 ])  *   256 ;
136                       if  ( ! isEncrypted) {
137                           if  (compressedSize  >   0 ) {
138                               throw   new  IllegalStateException( " ZIP not password protected. " );
139                          }
140                          state  =  State.SIGNATURE;
141                      }  else  {
142                          state  =  State.HEADER;
143                      }
144                       break ;
145                   case  HEADER:
146                      section  =  Section.FILE_DATA;
147                      initKeys();
148                       byte  lastValue  =   0 ;
149                       for  ( int  i  =   0 ; i  <  DECRYPT_HEADER_SIZE; i ++ ) {
150                          lastValue  =  ( byte ) (result  ^  decryptByte());
151                          updateKeys(lastValue);
152                          result  =  delegateRead();
153                      }
154                       if  ((lastValue  &   0xff !=  crc) {
155  //                         throw new IllegalStateException("Wrong password!");
156                      }
157                      compressedSize  -=  DECRYPT_HEADER_SIZE;
158                      state  =  State.DATA;
159                       //  intentionally no break
160                   case  DATA:
161                       if  (compressedSize  ==   - 1   &&  peekAheadEquals(DD_SIGNATURE)) {
162                          section  =  Section.DATA_DESCRIPTOR;
163                          skipBytes  =   5 ;
164                          state  =  State.CRC;
165                      }  else  {
166                          result  =  (result  ^  decryptByte())  &   0xff ;
167                          updateKeys(( byte ) result);
168                          compressedSize -- ;
169                           if  (compressedSize  ==   0 ) {
170                              state  =  State.SIGNATURE;
171                          }
172                      }
173                       break ;
174               case  TAIL:
175                       //  do nothing
176              }
177          }  else  {
178              skipBytes -- ;
179          }
180           return  result;
181      }
182 
183       private   static   final   int  BUF_SIZE  =   8 ;
184       private   int  bufOffset  =  BUF_SIZE;
185       private   final   int [] buf  =   new   int [BUF_SIZE];
186 
187       private   int  delegateRead()  throws  IOException {
188          bufOffset ++ ;
189           if  (bufOffset  >=  BUF_SIZE) {
190              fetchData( 0 );
191              bufOffset  =   0 ;
192          }
193           return  buf[bufOffset];
194      }
195 
196       private   boolean  peekAheadEquals( int [] values)  throws  IOException {
197          prepareBuffer(values);
198           for  ( int  i  =   0 ; i  <  values.length; i ++ ) {
199               if  (buf[bufOffset  +  i]  !=  values[i]) {
200                   return   false ;
201              }
202          }
203           return   true ;
204      }
205 
206       private   void  prepareBuffer( int [] values)  throws  IOException {
207           if  (values.length  >  (BUF_SIZE  -  bufOffset)) {
208               for  ( int  i  =  bufOffset; i  <  BUF_SIZE; i ++ ) {
209                  buf[i  -  bufOffset]  =  buf[i];
210              }
211              fetchData(BUF_SIZE  -  bufOffset);
212              bufOffset  =   0 ;
213          }
214      }
215 
216       private   void  peekAhead( int [] values)  throws  IOException {
217          prepareBuffer(values);
218          System.arraycopy(buf, bufOffset, values,  0 , values.length);
219      }
220 
221       private   void  overrideBuffer( int [] values)  throws  IOException {
222          prepareBuffer(values);
223          System.arraycopy(values,  0 , buf, bufOffset, values.length);
224      }
225 
226       private   void  fetchData( int  offset)  throws  IOException {
227           for  ( int  i  =  offset; i  <  BUF_SIZE; i ++ ) {
228              buf[i]  =  delegate.read();
229               if  (buf[i]  ==   - 1 ) {
230                   break ;
231              }
232          }
233      }
234 
235      @Override
236       public   void  close()  throws  IOException {
237          delegate.close();
238           super .close();
239      }
240 
241       private   void  initKeys() {
242          System.arraycopy(pwdKeys,  0 , keys,  0 , keys.length);
243      }
244 
245       private   void  updateKeys( byte  charAt) {
246          ZipUtil.updateKeys(charAt, keys);
247      }
248 
249       private   byte  decryptByte() {
250           int  temp  =  keys[ 2 |   2 ;

251           return  ( byte ) ((temp  *  (temp  ^   1 ))  >>>   8 );
252      }
253  }

2.
  1  import  java.io.IOException;
  2  import  java.io.OutputStream;
  3  import  java.security.SecureRandom;
  4  import  java.util.ArrayList;
  5  import  java.util.Arrays;
  6  import   static  research.zip.ZipUtil. * ;
  7 
  8  /**
  9   * Output stream that can be used to password-protect zip files.
 10   * 
 11   * <h3>Example usage:</h3>
 12   * <p>
 13   * Creating a password-protected zip file:
 14   * </p>
 15   * 
 16   * <pre>
 17   *  ZipEncryptOutputStream zeos = new ZipEncryptOutputStream(new FileOutputStream(fileName), password);
 18   *  ZipOutputStream zos = new ZipOuputStream(zdis);
 19   *   create zip file using the standard JDK ZipOutputStream in zos variable 
 20   * </pre>
 21   * <p>
 22   * Converting a plain zip file to a password-protected zip file:
 23   * </p>
 24   * 
 25   * <pre>
 26   * FileInputStream src = new FileInputStream( srcFile );
 27   * ZipEncryptOutputStream dest = new ZipEncryptOutputStream( new FileOutputStream( destFile ), password );
 28   * 
 29   * // should wrap with try-catch-finally, do the close in finally
 30   * int b;
 31   * while (( b = src.read() ) &gt; -1) {
 32   *     dest.write( b );
 33   * }
 34   * 
 35   * src.close();
 36   * dest.close();
 37   * </pre>
 38   * 
 39   *  @author  Martin Matula (martin at alutam.com)
 40    */
 41  public   class  ZipEncryptOutputStream  extends  OutputStream {
 42       private   final  OutputStream delegate;
 43       private   final   int  keys[]  =   new   int [ 3 ];
 44       private   final   int  pwdKeys[]  =   new   int [ 3 ];
 45 
 46       private   int  copyBytes;
 47       private   int  skipBytes;
 48       private  State state  =  State.NEW_SECTION;
 49       private  State futureState;
 50       private  Section section;
 51       private   byte [] decryptHeader;
 52       private   final  ArrayList < int [][] >  crcAndSize  =   new  ArrayList < int [][] > ();
 53       private   final  ArrayList < Integer >  localHeaderOffset  =   new  ArrayList < Integer > ();
 54       private  ArrayList < int [] >  fileData;
 55       private   int [][] condition;
 56       private   int  fileIndex;
 57       private   int [] buffer;
 58       private   int  bufOffset;
 59       private   int  fileSize;
 60       private   int  bytesWritten;
 61       private   int  centralRepoOffset;
 62 
 63       private   static   final   int  ROW_SIZE  =   65536 ;
 64 
 65       /**
 66       * Convenience constructor taking password as a string.
 67       * 
 68       *  @param  delegate
 69       *            Output stream to write the password-protected zip to.
 70       *  @param  password
 71       *            Password to use for protecting the zip.
 72        */
 73       public  ZipEncryptOutputStream( OutputStream delegate, String password ) {
 74           this ( delegate, password.toCharArray() );
 75      }
 76 
 77       /**
 78       * Safer version of the constructor. Takes password as a char array that can
 79       * be nulled right after calling this constructor instead of a string that
 80       * may stay visible on the heap for the duration of application run time.
 81       * 
 82       *  @param  delegate
 83       *            Output stream to write the password-protected zip to.
 84       *  @param  password
 85       *            Password to use for protecting the zip.
 86        */
 87       public  ZipEncryptOutputStream( OutputStream delegate,  char [] password ) {
 88           this .delegate  =  delegate;
 89          pwdKeys[ 0 =   305419896 ;
 90          pwdKeys[ 1 =   591751049 ;
 91          pwdKeys[ 2 =   878082192 ;
 92           for  (  int  i  =   0 ; i  <  password.length; i ++  ) {
 93              ZipUtil.updateKeys( ( byte ) ( password[i]  &   0xff  ), pwdKeys );
 94          }
 95      }
 96 
 97       private   static   enum  State {
 98          NEW_SECTION, SECTION_HEADER, FLAGS, REPO_OFFSET, CRC, FILE_HEADER_OFFSET, COMPRESSED_SIZE_READ, HEADER, DATA, FILE_BUFFERED, BUFFER, BUFFER_COPY, BUFFER_UNTIL, TAIL
 99      }
100 
101       private   static   enum  Section {
102          LFH, CFH, ECD
103      }
104 
105      @Override
106       public   void  write(  int  b )  throws  IOException {
107           if  ( skipBytes  >   0  ) {
108              skipBytes -- ;
109               return ;
110          }
111           if  ( copyBytes  ==   0  ) {
112               switch  (state) {
113               case  NEW_SECTION:
114                   if  ( b  !=   0x50  ) {
115                       throw   new  IllegalStateException(  " Unexpected value read at offset  "   +  bytesWritten  +   " "   +  b  +   "  (expected:  "   +   0x50   +   " ) "  );
116                  }
117                  buffer(  new   int [ 4 ], State.SECTION_HEADER,  0x50  );
118                   return ;
119               case  SECTION_HEADER:
120                  identifySectionHeader();
121                   break ;
122               case  FLAGS:
123                  copyBytes  =   7 ;
124                  state  =  State.CRC;
125                   if  ( section  ==  Section.LFH ) {
126                       if  ( ( b  &   1  )  ==   1  ) {
127                           throw   new  IllegalStateException(  " ZIP already password protected. "  );
128                      }
129                       if  ( ( b  &   64  )  ==   64  ) {
130                           throw   new  IllegalStateException(  " Strong encryption used. "  );
131                      }
132                       if  ( ( b  &   8  )  ==   8  ) {
133                          bufferUntil( State.FILE_BUFFERED, CFH_SIGNATURE, LFH_SIGNATURE );
134                      }
135                  }
136                  b  =  b  &   0xf7   |   1 ;
137                   break ;
138               case  CRC:
139                   if  ( section  ==  Section.CFH ) {
140                       int [][] cns  =  crcAndSize.get( fileIndex );
141                       for  (  int  j  =   0 ; j  <   3 ; j ++  ) {
142                           for  (  int  i  =   0 ; i  <   4 ; i ++  ) {
143                              writeToDelegate( cns[j][i] );
144                          }
145                      }
146                      skipBytes  =   11 ;
147                      copyBytes  =   14 ;
148                      state  =  State.FILE_HEADER_OFFSET;
149                  }  else  {
150                       int [] cns  =   new   int [ 16 ];
151                      buffer( cns, State.COMPRESSED_SIZE_READ, b );
152                  }
153                   return ;
154               case  FILE_HEADER_OFFSET:
155                  writeAsBytes( localHeaderOffset.get( fileIndex ) );
156                  fileIndex ++ ;
157                  skipBytes  =   3 ;
158                  copyBytesUntil( State.SECTION_HEADER, CFH_SIGNATURE, ECD_SIGNATURE );
159                   return ;
160               case  COMPRESSED_SIZE_READ:
161                   int [][] cns  =   new   int [][] {
162                          { buffer[ 0 ], buffer[ 1 ], buffer[ 2 ], buffer[ 3 ] },
163                          { buffer[ 4 ], buffer[ 5 ], buffer[ 6 ], buffer[ 7 ] },
164                          { buffer[ 8 ], buffer[ 9 ], buffer[ 10 ], buffer[ 11 ] } };
165                  adjustSize( cns[ 1 ] );
166                  crcAndSize.add( cns );
167                   for  (  int  j  =   0 ; j  <   3 ; j ++  ) {
168                       for  (  int  i  =   0 ; i  <   4 ; i ++  ) {
169                          writeToDelegate( cns[j][i] );
170                      }
171                  }
172                  copyBytes  =  buffer[ 12 +  buffer[ 14 +  ( buffer[ 13 +  buffer[ 15 ] )  *   256   -   1 ;
173                  state  =  State.HEADER;
174                   if  ( copyBytes  <   0  ) {
175                       throw   new  IllegalStateException(  " No file name stored in the zip file. "  );
176                  }
177                   break ;
178               case  HEADER:
179                  writeDecryptHeader();
180                  fileSize  =  decode( crcAndSize.get( crcAndSize.size()  -   1  )[ 1 ] );
181                  state  =  State.DATA;
182                   //  intentionally no break
183               case  DATA:
184                  b  =  encrypt( b );
185                  fileSize -- ;
186                   if  ( fileSize  ==   0  ) {
187                      state  =  State.NEW_SECTION;
188                  }
189                   break ;
190               case  BUFFER:
191                  buffer[bufOffset]  =  b;
192                  bufOffset ++ ;
193                   if  ( bufOffset  ==  buffer.length ) {
194                      state  =  futureState;
195                  }
196                   return ;
197               case  BUFFER_COPY:
198                  buffer[bufOffset]  =  b;
199                   if  ( checkCondition() ) {
200                      bufOffset  =   0 ;
201                      state  =  futureState;
202                  }
203                   break ;
204               case  BUFFER_UNTIL:
205                   int  col  =  fileSize  %  ROW_SIZE;
206                   if  ( col  ==   0  ) {
207                      fileData.add(  new   int [ROW_SIZE] );
208                  }
209                   int [] row  =  fileData.get( fileData.size()  -   1  );
210                  row[col]  =  b;
211                  buffer[bufOffset]  =  b;
212                  fileSize ++ ;
213                   if  ( checkCondition() ) {
214                      fileSize  -=  buffer.length;
215                      state  =  futureState;
216                  }
217                   return ;
218               case  FILE_BUFFERED:
219                  row  =  fileData.get(  0  );
220                   int  r  =   0 ;
221                   int  pointer  =   16   +  row[ 12 +  row[ 14 +  ( row[ 13 +  row[ 15 ] )  *   256 ;
222                  cns  =   new   int [ 3 ][ 4 ];
223                  readFromFileBuffer( fileSize  -   12 , cns[ 0 ] );
224                  readFromFileBuffer( fileSize  -   8 , cns[ 1 ] );
225                  readFromFileBuffer( fileSize  -   4 , cns[ 2 ] );
226                  fileSize  =  decode( cns[ 1 ] );
227                  adjustSize( cns[ 1 ] );
228                  crcAndSize.add( cns );
229                   for  (  int  i  =   0 ; i  <   4 ; i ++  ) {
230                      row[i]  =  cns[ 0 ][i];
231                      row[i  +   4 =  cns[ 1 ][i];
232                      row[i  +   8 =  cns[ 2 ][i];
233                  }
234                   for  (  int  i  =   0 ; i  <  pointer; i ++  ) {
235                      writeToDelegate( row[i] );
236                  }
237                  writeDecryptHeader();
238                   for  (  int  i  =   0 ; i  <  fileSize; i ++  ) {
239                      writeToDelegate( encrypt( row[pointer] ) );
240                      pointer ++ ;
241                       if  ( pointer  ==  ROW_SIZE ) {
242                          pointer  =   0 ;
243                          r ++ ;
244                          row  =  fileData.get( r );
245                      }
246                  }
247                  fileData  =   null ;
248                  identifySectionHeader();
249                   break ;
250               case  REPO_OFFSET:
251                  writeAsBytes( centralRepoOffset );
252                  skipBytes  =   3 ;
253                  state  =  State.TAIL;
254                   return ;
255               case  TAIL:
256                   break ;
257              }
258          }  else  {
259              copyBytes -- ;
260          }
261          writeToDelegate( b );
262      }
263 
264       private   void  writeToDelegate(  int  b )  throws  IOException {
265          delegate.write( b );
266          bytesWritten ++ ;
267      }
268 
269       private   static   void  adjustSize(  int [] values ) {
270           int  inc  =  DECRYPT_HEADER_SIZE;
271           for  (  int  i  =   0 ; i  <   4 ; i ++  ) {
272              values[i]  =  values[i]  +  inc;
273              inc  =  values[i]  >>   8 ;
274              values[i]  &=   0xff ;
275          }
276      }
277 
278       private   static   int  decode(  int [] value ) {
279           return  value[ 0 +  ( value[ 1 <<   8  )  +  ( value[ 2 <<   16  )  +  ( value[ 3 <<   24  );
280      }
281 
282       private   void  writeAsBytes(  int  value )  throws  IOException {
283           for  (  int  i  =   0 ; i  <   4 ; i ++  ) {
284              writeToDelegate( value  &   0xff  );
285              value  >>=   8 ;
286          }
287      }
288 
289       private   void  identifySectionHeader()  throws  IllegalStateException,
290              IOException {
291           if  ( Arrays.equals( buffer, LFH_SIGNATURE ) ) {
292              section  =  Section.LFH;
293              copyBytes  =   1 ;
294              state  =  State.FLAGS;
295              localHeaderOffset.add( bytesWritten );
296          }  else   if  ( Arrays.equals( buffer, CFH_SIGNATURE ) ) {
297              section  =  Section.CFH;
298              copyBytes  =   3 ;
299              state  =  State.FLAGS;
300               if  ( centralRepoOffset  ==   0  ) {
301                  centralRepoOffset  =  bytesWritten;
302              }
303          }  else   if  ( Arrays.equals( buffer, ECD_SIGNATURE ) ) {
304              section  =  Section.ECD;
305              copyBytes  =   11 ;
306              state  =  State.REPO_OFFSET;
307          }  else  {
308               throw   new  IllegalStateException(  " Unknown header:  "   +  Arrays.asList( buffer ).toString() );
309          }
310          flushBuffer();
311      }
312 
313       private   void  readFromFileBuffer(  int  offset,  int [] target ) {
314           int  r  =  offset  /  ROW_SIZE;
315           int  c  =  offset  %  ROW_SIZE;
316           int [] row  =  fileData.get( r );
317           for  (  int  i  =   0 ; i  <  target.length; i ++  ) {
318              target[i]  =  row[c];
319              c ++ ;
320               if  ( c  ==  ROW_SIZE ) {
321                  c  =   0 ;
322                  r ++ ;
323                  row  =  fileData.get( r );
324              }
325          }
326      }
327 
328      @Override
329       public   void  close()  throws  IOException {
330           super .close();
331          delegate.close();
332      }
333 
334       private   void  initKeys() {
335          System.arraycopy( pwdKeys,  0 , keys,  0 , keys.length );
336      }
337 
338       private   void  updateKeys(  byte  charAt ) {
339          ZipUtil.updateKeys( charAt, keys );
340      }
341 
342       private   byte  encryptByte() {
343           int  temp  =  keys[ 2 |   2 ;
344           return  ( byte ) ( ( temp  *  ( temp  ^   1  ) )  >>>   8  );
345      }
346 
347       private   int  encrypt(  int  b ) {
348           int  newB  =  ( b  ^  encryptByte() )  &   0xff ;
349          updateKeys( ( byte ) b );
350           return  newB;
351      }
352 
353       private   void  writeDecryptHeader()  throws  IOException {
354          initKeys();
355           int [] crc  =  crcAndSize.get( crcAndSize.size()  -   1  )[ 0 ];
356          SecureRandom random  =   new  SecureRandom();
357          decryptHeader  =   new   byte [DECRYPT_HEADER_SIZE];
358          random.nextBytes( decryptHeader );
359          decryptHeader[DECRYPT_HEADER_SIZE  -   2 =  ( byte ) crc[ 2 ];
360          decryptHeader[DECRYPT_HEADER_SIZE  -   1 =  ( byte ) crc[ 3 ];
361           for  (  int  i  =   0 ; i  <  DECRYPT_HEADER_SIZE; i ++  ) {
362              writeToDelegate( encrypt( decryptHeader[i] ) );
363          }
364      }
365 
366       private   void  buffer(  int [] values, State state,  int  knownValues ) {
367          System.arraycopy( knownValues,  0 , values,  0 , knownValues.length );
368          buffer  =  values;
369          bufOffset  =  knownValues.length;
370           this .state  =  State.BUFFER;
371          futureState  =  state;
372      }
373 
374       private   void  flushBuffer()  throws  IOException {
375           for  (  int  i  =   0 ; i  <  bufOffset; i ++  ) {
376              writeToDelegate( buffer[i] );
377          }
378      }
379 
380       private   void  copyBytesUntil( State state,  int [] condition ) {
381          futureState  =  state;
382           this .condition  =  condition;
383          bufOffset  =   0 ;
384          buffer  =   new   int [condition[ 0 ].length];
385           this .state  =  State.BUFFER_COPY;
386      }
387 
388       private   void  bufferUntil( State state,  int [] condition ) {
389          copyBytesUntil( state, condition );
390          fileData  =   new  ArrayList < int [] > ();
391          fileSize  =   0 ;
392           this .state  =  State.BUFFER_UNTIL;
393      }
394 
395       private   boolean  checkCondition() {
396           boolean  equals  =   true ;
397           for  (  int  i  =   0 ; i  <  condition.length; i ++  ) {
398              equals  =   true ;
399               for  (  int  j  =   0 ; j  <=  bufOffset; j ++  ) {
400                   if  ( condition[i][j]  !=  buffer[j] ) {
401                      equals  =   false ;
402                       break ;
403                  }
404              }
405               if  ( equals ) {
406                  bufOffset ++ ;
407                   break ;
408              }
409          }
410           if  (  ! equals ) {
411              bufOffset  =   0 ;
412          }
413           return  equals  &&  ( buffer.length  ==  bufOffset );
414      }
415  }


3.
 1  /**
 2   * 
 3   *  @author  Martin Matula (martin at alutam.com)
 4    */
 5  class  ZipUtil {
 6       static   final   int [] CRC_TABLE  =   new   int [ 256 ];
 7       //  compute the table
 8       //  (could also have it pre-computed - see
 9       //   http://snippets.dzone.com/tag/crc32 )
10       static  {
11           for  (  int  i  =   0 ; i  <   256 ; i ++  ) {
12               int  r  =  i;
13               for  (  int  j  =   0 ; j  <   8 ; j ++  ) {
14                   if  ( ( r  &   1  )  ==   1  ) {
15                      r  =  ( r  >>>   1  )  ^   0xedb88320 ;
16                  }  else  {
17                      r  >>>=   1 ;
18                  }
19              }
20              CRC_TABLE[i]  =  r;
21          }
22      }
23 
24       static   final   int  DECRYPT_HEADER_SIZE  =   12 ;
25       static   final   int [] CFH_SIGNATURE  =  {  0x50 0x4b 0x01 0x02  };
26       static   final   int [] LFH_SIGNATURE  =  {  0x50 0x4b 0x03 0x04  };
27       static   final   int [] ECD_SIGNATURE  =  {  0x50 0x4b 0x05 0x06  };
28       static   final   int [] DD_SIGNATURE  =  {  0x50 0x4b 0x07 0x08  };
29 
30       static   void  updateKeys(  byte  charAt,  int [] keys ) {
31          keys[ 0 =  crc32( keys[ 0 ], charAt );
32          keys[ 1 +=  keys[ 0 &   0xff ;
33          keys[ 1 =  keys[ 1 *   134775813   +   1 ;
34          keys[ 2 =  crc32( keys[ 2 ], ( byte ) ( keys[ 1 >>   24  ) );
35      }
36 
37       static   int  crc32(  int  oldCrc,  byte  charAt ) {
38           return  ( ( oldCrc  >>>   8  )  ^  CRC_TABLE[( oldCrc  ^  charAt )  &   0xff ] );
39      }
40 
41       static   enum  State {
42          SIGNATURE, FLAGS, COMPRESSED_SIZE, FN_LENGTH, EF_LENGTH, HEADER, DATA, TAIL, CRC
43      }
44 
45       static   enum  Section {
46          FILE_HEADER, FILE_DATA, DATA_DESCRIPTOR
47      }
48  }


你可能感兴趣的:(Java方法进行解压/生成有密码保护的压缩文件(zip格式))