0

Javaファイルのすべてのエントリを読み取り、ファイルの内容のみに基づいてZipInputStream処理するために、次のメソッドを作成しました。私のクラスの中には:MD5Tczip

 public String digest( ZipInputStream entry ) throws IOException{

            byte[] digest = null;
            MessageDigest md5 = null;
            String mdEnc = "";
            ZipEntry current;

            try {
                md5 = MessageDigest.getInstance( "MD5" );
                if( entry != null ) {
                    while(( current = entry.getNextEntry() ) != null ) {
                        if( current.isDirectory() ) {
                            digest = this.encodeUTF8( current.getName() );
                            md5.update( digest );
                        }
                        else{
                            int size = ( int )current.getSize();
                            if(size > 0){
                                digest = new byte[ size ];
                                entry.read( digest, 0, size );
                                md5.update( digest );
                            }
                        }
                    }
                    digest = md5.digest();
                    mdEnc = new BigInteger( 1, md5.digest() ).toString( 16 );
                    entry.close();
                }
            }
            catch ( NoSuchAlgorithmException e ) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            catch (IllegalArgumentException ex){
                System.out.println("There is an illegal encoding.");
                //
                // The fix for Korean/Chinese/Japanese encodings goes here
                //
                Charset encoding = Charset.forName("utf-8");
                ZipInputStream zipinputstream = 
                        new ZipInputStream(new FileInputStream( this.filename ), encoding);
                digest = new byte[ 1024 ];
                current = zipinputstream.getNextEntry();
                while (current != null) { //for each entry to be extracted
                    String entryName = current.getName();
                    System.out.println("Processing: " + entryName);
                    int n;
                    FileOutputStream fileoutputstream = 
                            new FileOutputStream( this.filename );

                    while (( n = zipinputstream.read( digest, 0, 1024 )) > -1) {
                        fileoutputstream.write(digest, 0, n);
                    }

                    fileoutputstream.close(); 
                    zipinputstream.closeEntry();
                    current = zipinputstream.getNextEntry();
                }//while
                zipinputstream.close();
            }
            return mdEnc;
        }

        public byte[] encodeUTF8( String name ) {
            final Charset UTF8_CHARSET = Charset.forName( "UTF-8" );
            return name.getBytes( UTF8_CHARSET );
        }

次に、プログラムはルートディレクトリ(別名)を調べ、すべてのディレクトリを繰り返し処理して、処理するファイルをC:\workspace\path\to\source\code探します。.zipこれらのファイルは次のようになりますFile[] files

public void showFiles( File[] files ){
        for( File file : files ){
            if( file.isDirectory() ) {
                showFiles( file.listFiles( this.filter ) );
            }
            else {
                try {
                    String path = file.getCanonicalPath();
                    String relative = path.replace("tc10.0.0.2012080100_A", "tc10.0.0.2012080600_C" );
                    File b = new File(relative);
                    if( b.exists() ) {
                        System.out.println( "Processing :" + file.getName() );
                        this.zip_a = new Tczip( path );
                        this.zip_b = new Tczip( relative );
                        String md5_a = this.zip_a.digest();
                        String md5_b = this.zip_b.digest();
                        System.out.println("MD5 A: " + md5_a);
                        System.out.println("MD5 B: " + md5_b);

                        if( md5_a.equals( md5_b )){
                            System.out.println( "They Match" );
                        }
                        else {
                            System.out.println( "They don't Match" );
                        }
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

そこでMD5、これらすべてのzipファイルを処理し、それらが一致するかどうかを比較したいと思いました。2つの同等の(コンテンツ内の)ZIPファイルが同じMD5を持つことが期待されます。ファイルの内容が同じでない場合は、MD5が異なります。ただし、プログラムを実行すると、次のようになります。

Processing :web.zip
MD5 A: d41d8cd98f00b204e9800998ecf8427e
MD5 B: d41d8cd98f00b204e9800998ecf8427e
They Match
Processing :weldmgmt_icons.zip
MD5 A: d41d8cd98f00b204e9800998ecf8427e
MD5 B: d41d8cd98f00b204e9800998ecf8427e
They Match
Processing :weldmgmt_install.zip
MD5 A: d41d8cd98f00b204e9800998ecf8427e
MD5 B: d41d8cd98f00b204e9800998ecf8427e
They Match
Processing :weldmgmt_template.zip
MD5 A: d41d8cd98f00b204e9800998ecf8427e
MD5 B: d41d8cd98f00b204e9800998ecf8427e
They Match

なぜそれらは同じMD5ですか?2つのファイルが同じであると期待していますが、MD5すべてではありません。助言がありますか?私は何が間違っているのですか?

4

1 に答える 1

0

次のコード行を信じています。

while(( current = entry.getNextEntry() ) != null ) {
                    if( current.isDirectory() ) {
                        digest = this.encodeUTF8( current.getName() );
                        md5.update( digest );
                    }
                    else{
                        int size = ( int )current.getSize();
                        if(size > 0){
                            digest = new byte[ size ];
                            entry.read( digest, 0, size );
                            md5.update( digest );
                        }
                    }
                }

この実装が失敗する場所です。したがって、APIを見ると、 entry.getNextEntry() を呼び出すと、次に処理するファイルが返されます。ただし、それが ではない場合、その値を破棄していますdirectoryentry.readしたがって、毎回同じ行で同じファイルを処理しているだけなので、ハッシュが同じであることは理にかなっています。

アップデート

これを修正するには、次の行に沿って何かを実行できる必要があります。entry = entry.getNextEntry(); または、他の人の苦痛を軽減するには、次のようにします。currentEntry = entry.getNextEntry();

于 2012-08-22T12:45:15.280 に答える