2010-12-03 5 views
2

Ich muss Dateien mit Java mit einem CRC32-Code vergleichen, der von einem C# -Skript bereitgestellt wird. Wenn ich den CRC32 mit java.util.zip.CRC32 errechne, ist das Ergebnis völlig anders ...Java CRC32: nicht dasselbe wie CRC von C#

Meine Vermutung ist, dass das Polynom = 0x2033 des C# -Skriptes nicht das gleiche wie in zip.CRC32 ist. Ist es möglich, das Polynom einzustellen? Oder irgendwelche Ideen einer Java-Klasse für die Berechnung eines CRC32, wo Sie Ihr eigenes Polynom definieren können?

UPDATE: Problem ist nicht das Polymnom. Das ist das gleiche zwischen C# und Java

Das ist mein Code, vielleicht ist etwas falsch in der Art, wie ich die Datei lese?

package com.mine.digits.internal.contentupdater; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.zip.CRC32; 

public class CRC 
{ 
    public static String doConvert32(File file) 
    { 
     byte[] bytes = readBytesFromFile(file); // readFromFile(file).getBytes(); 

     CRC32 x = new CRC32(); 
     x.update(bytes); 

     return (Long.toHexString(x.getValue())).toUpperCase(); 
    } 

    /** Read the contents of the given file. */ 
    private static byte[] readBytesFromFile(File file) 
    { 
     try 
     { 
      InputStream is = new FileInputStream(file); 

      long length = file.length(); 
      if (length > Integer.MAX_VALUE) { 
       // File is too large 
      } 

      byte[] bytes = new byte[(int)length]; 
      int offset = 0; 
      int numRead = 0; 
      while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) 
      { 
       offset += numRead; 
      } 

      // Ensure all the bytes have been read in 
      if (offset < bytes.length) { 
       System.out.println("Could not completely read file " + file.getName()); 
      } 

      // Close the input stream and return bytes 
      is.close(); 

      return bytes; 
     } 
     catch (IOException e) 
     { 
      System.out.println("IOException " + file.getName()); 

      return null; 
     } 
    } 
} 

Vielen Dank, Frank

+5

Die Alternativen sind: a) Sie verwenden die API nicht korrekt aus Java, C# oder beiden; b) Der von Ihnen verwendete C# -Code ist fehlerhaft. Ohne Ihren Code oder den von Ihnen verwendeten C# -Code zu sehen, ist es schwer zu sagen. Ein paar kurze aber komplette Programme mit einer kleinen Menge von Testdaten würde wirklich helfen. –

+1

FYI: [Es ist buchstabiert "Java", nicht "JAVA".] (Http://programmers.stackexchange.com/q/2271/241) –

+0

Ihr Java-Code sieht OK, vielleicht ist etwas auf der C# -Seite falsch? – Grodriguez

Antwort

0

gelöst, indem Sie den Code aus C# Kopieren und auf eine Java-Klasse konvertieren ...

So, jetzt verwenden beide den gleichen Code, musste nur für einige kleinere Änderungen tun unsigned <> unterzeichnet Bytes Unterschiede.

+2

Ok, und wie sah der C# -Code aus? – t0r0X

3

Der Standard (IEEE) CRC32 Polynom ist 0x04C11DB7, die entspricht:

x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + 
x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 

Dies ist, was Anwendungen java.util.zip.CRC32 . Sie wissen nicht, über die C# Skript Sie erwähnen ...

Sie diese Code-Schnipsel finden nützlich:

1

CRC-32 ist eine spezifische CRC-Variante nach IEEE 802.3 und verwendet das Polynom 0x04C11DB7. Wenn Ihre C# -Bibliothek das Polynom 0x2033 verwendet, ist es/nicht/eine Implementierung von CRC-32.

Wenn Sie Java-Code benötigen, um beliebige CRC-Varianten zu berechnen, erhalten Sie mit google "java crc" mehrere Beispiele.

+0

Ok, ich untersuchte das ein bisschen weiter und fand heraus, dass C# tatsächlich 0x04C11DB7 verwendet, also ist das für die Java-Klasse dasselbe. Problem muss woanders sein, warum mein crc nicht auf C# und JAVA gleich ist ... – Frank

+0

Für CRCs, auch die endiannes zählt. CRCs verarbeiten keine Bytes; stattdessen arbeiten sie an Bitströmen. Daher, wenn Sie Probleme mit der Bit-Reihenfolge innerhalb von Bytes oder Byte-Reihenfolgen innerhalb von Wörtern haben, erhalten Sie nicht das gleiche Ergebnis. – Schedler

+0

@Schedler: Die meisten CRC-Algorithmusimplementierungen arbeiten jeweils mit einem Byte, daher sollte es keine Byte-Reihenfolge geben. Und wenn, dann ist das ein Fehler in der Implementierung. – Grodriguez

0

1 + x + x^2 + x^4 + x^5 + x^7 + x^8 + x^10 + x^11 + x^12 + x^16 + x^22 + x^23 + x^26 (0x04C11DB7) Java verwendet das obige Polynom für die CRC 32-Berechnung und unterscheidet sich vom IEEE 802.3-Standard, der zusätzlich eine 32-Bit-Potenz von x hat.

+0

Der x^32-Teil wird lautlos hinzugefügt. – ikrabbe