# Prüfsumme mit CRC32



## kamus (29. Okt 2008)

Hallo,

ich habe unter Java mit CheckedInputStream eine Prüfsumme mit CRC32 von einem FileStream erstellt. Dann habe ich den Inhalt des Streams in ein Byte[] geschrieben und über HTTP Post als Datei gesandt. Auf dem Server habe ich dann mit PHP über 
	
	
	
	





```
hash_file('CRC32', $file, FALSE)
```
 die Prüfsumme für die Datei ermittelt. Leider kommt immer ein anderer Wert heraus als auf Clientseite. Ich weiss nicht was der InputStream unter Java am Dateiinhalt umwandelt, dass ein anderer Wert entsteht. Die Datei kommt jedenfalls korrekt am Server an.

Vielleicht kann jemand helfen.

Danke


----------



## HoaX (29. Okt 2008)

wie schauen denn die ergebnisse aus? beispieldaten/programm?


----------



## maki (29. Okt 2008)

>> und über HTTP Post als Datei gesandt

HTTP ist nur für Text geeignet, Binärdaten werden mit Base64 Codiert und sind dann Text, vielleicht liegt es daran.


----------



## kamus (29. Okt 2008)

hier der Code


```
private Vector<byte[]> splitFile( String fileName ) {
		Vector<byte[]> bytes = new Vector<byte[]>();
		try {
            CheckedInputStream cis = null;
            long fileSize = 0;
            try {
                // Computer CRC32 checksum
                cis = new CheckedInputStream( new FileInputStream(fileName), new CRC32());
                fileSize = new File(fileName).length();
            } catch (FileNotFoundException e) {
                System.err.println(Messages.getString("Upload.49")); //$NON-NLS-1$
                System.exit(1);
            }
            byte[] buf = new byte[1024 * 1000];
            int count = 0;
            while ( (count = cis.read(buf)) != -1 ) {
            	byte[] buf_copy = new byte[count];
            	System.arraycopy( buf, 0, buf_copy, 0, count);
               bytes.addElement( buf_copy );
            }
            crc32 = cis.getChecksum().getValue();
            cis.close();
            System.out.println( crc32 + Messages.getString("Upload.50") + fileSize + Messages.getString("Upload.51") + fileName); //$NON-NLS-1$ //$NON-NLS-2$
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
    }
    return bytes;
}
```

und ausgegeben wird von Java *3586336226* und von PHP *70b5e1ac*.

HTTP kann eigentlich nicht der Grund sein, weil die Datei nach dem Upload ja funktioniert (Video), also im Originalzustand vorliegen müsste.


----------



## maki (29. Okt 2008)

>> HTTP kann eigentlich nicht der Grund sein, weil die Datei nach dem Upload ja funktioniert (Video), also im Originalzustand vorliegen müsste.

Binärströme werden immer als Base64 über HTTP verschickt.


----------



## kamus (29. Okt 2008)

mag sein, aber ich lese die Datei über PHP ja erst ein, nachdem sie auf Serverseite schon abgespeichert wurde und dort den gleichen Inhalt hat wie vorher.

Ich glaube, dass die Abweichung auf Javaseite passiert, da ich dem CheckedInputStream einen InputStream übergeben muss. Die Daten liegen dann in einem ByteArray. Aber wie kann ich die Daten temporär wieder in ein Format bringen, welches dem auf PHPseite beim Einlesen aus der Datei entspricht.


----------



## HoaX (29. Okt 2008)

liegt an php, nimm crc32(file_get_contents($fileName)) und du erhälst das gleiche wie mit java Long.toString(crc32.getValue(), 16)

siehe auch letzter kommentar auf php.net/hash_file ...


----------



## kamus (29. Okt 2008)

der geänderte Code

Java


```
private Vector<byte[]> splitFile( String fileName ) {
		Vector<byte[]> bytes = new Vector<byte[]>();
		try {
            CheckedInputStream cis = null;
            long fileSize = 0;
            try {
                // Computer CRC32 checksum
                cis = new CheckedInputStream( new FileInputStream(fileName), new CRC32());
                fileSize = new File(fileName).length();
            } catch (FileNotFoundException e) {
                System.err.println(Messages.getString("Upload.49")); //$NON-NLS-1$
                System.exit(1);
            }
            byte[] buf = new byte[1024 * 1000];
            int count = 0;
            while ( (count = cis.read(buf)) != -1 ) {
            	byte[] buf_copy = new byte[count];
            	System.arraycopy( buf, 0, buf_copy, 0, count);
                bytes.addElement( buf_copy );
            }
            crc32 = Long.toString( cis.getChecksum().getValue(), 16 );
            cis.close();
            System.out.println( crc32 + Messages.getString("Upload.50") + fileSize + Messages.getString("Upload.51") + fileName); //$NON-NLS-1$ //$NON-NLS-2$
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
        return bytes;
	}
```

PHP


```
$crc32 = crc32( file_get_contents( $file ) );
```

ergibt nun

PHP *-708631070* und Java *d5c325e2*

also auch keine Lösung. Vielleicht gibt es ja noch andere Vorschläge.


----------



## tuxedo (29. Okt 2008)

Ist dir noch nicht aufgefallen dass das eine HEX ist und das andere Decimal?

Versuch mal beides auf einen Nenner zu bringen. Und du wirst sehen: Das ist der gleiche Wert ... Nur eben signed/unsigned/dec/hex durcheinandergewürfelt ...

Probe: Mach mal den WIndows Taschenrechner auf und stell den auf wissenschaftlich. Dann kopiere den PHP Wert rein und stell auf HEX um... Erkennst du was?

- Alex


----------



## kamus (3. Nov 2008)

Vielen Dank für die Hilfe. Ich habe den Wert auf PHP-Seite mit der Funktion *dechex* umgewandelt und heraus kam der gleiche Wert, trotz negativem Vorzeichen.


----------

