簡體   English   中英

將crc代碼從C轉換為Java會產生意外結果

[英]Converting crc code from C to Java yields unexpected results

我正在嘗試將CRC C代碼轉換為Java,但沒有得到預期的結果。 這是我到目前為止所擁有的...

C代碼

#include <stdio.h>
#include <stdint.h>
#include <string.h>

//Partial code to unit test function

/// zlib's CRC32 polynomial
const uint32_t CrcPolynomial = 0xEDB88320;

/// compute CRC32 (bitwise algorithm)
uint32_t Crc32Bitwise(const void* data, size_t length, uint32_t previousCrc32)
{
    uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
    const uint8_t* current = (const uint8_t*) data;
    while (length-- > 0)
    {
    crc ^= *current++;

    for (int j = 0; j < 8; j++)
    {
        crc = (crc >> 1) ^ (-int32_t(crc & 1) & CrcPolynomial);
    }
    }
    return ~crc; // same as crc ^ 0xFFFFFFFF
}

/// compute CRC32 (half-byte algoritm)
uint32_t Crc32HalfByte(const void* data, size_t length, uint32_t previousCrc32 = 0)
{
    uint32_t crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
    const uint8_t* current = (const uint8_t*) data;

    /// look-up table for half-byte, same as crc32Lookup[0][16*i]
    static const uint32_t Crc32Lookup16[16] =
    {
    0x00000000,0x1DB71064,0x3B6E20C8,0x26D930AC,0x76DC4190,0x6B6B51F4,0x4DB26158,0x5005713C,
    0xEDB88320,0xF00F9344,0xD6D6A3E8,0xCB61B38C,0x9B64C2B0,0x86D3D2D4,0xA00AE278,0xBDBDF21C
    };

    while (length-- > 0)
    {
    crc = Crc32Lookup16[(crc ^  *current      ) & 0x0F] ^ (crc >> 4);
    crc = Crc32Lookup16[(crc ^ (*current >> 4)) & 0x0F] ^ (crc >> 4);
    current++;
    }

    return ~crc; // same as crc ^ 0xFFFFFFFF
}

int main(int argc, char * argv[])
{

const char* test_string = "Hello World";
printf("strlen of test_string %ld\n",strlen(test_string));
uint32_t test_crc32_bw = Crc32Bitwise((void*)test_string,strlen(test_string),0);
printf("test_crc32_bw = %d\n",(int32_t) test_crc32_bw);

uint32_t test_crc32_hb = Crc32HalfByte((void*)test_string,strlen(test_string),0);
printf("test_crc32_hb = %d\n",(int32_t) test_crc32_hb);


return 0;
}

結果

strlen of test_string 11
test_crc32_bw = 1243066710
test_crc32_hb = 1243066710

Java代碼

public class CRC32{


    /// zlib's CRC32 polynomial
private static final long CrcPolynomial = 0xEDB88320L;

public static int LongToInt(long value){
    return (int)(value & 0xFFFFFFFFL);
}

public static long Complement(long value){
    return (value ^ 0xFFFFFFFFL);
}
/// compute CRC32 (bitwise algorithm)
private static long Crc32Bitwise(byte[] data, long length, long previousCrc32)
{
    //long crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
    //force long to unsigned integer below
    long crc = Complement(previousCrc32);
    for (int i=0; i < data.length; i++)
    {
    crc ^= (data[i]);
    for (int j = 0; j < 8; j++)
    {
        crc = ((crc) >>> 1) ^ (-(long)((crc) & 1) & CrcPolynomial);
    }
    }
    return Complement(crc); //return crc ^ 0xFFFFFFFF;
}

/// compute CRC32 (bitwise algorithm)
private static long Crc32HalfByte(byte[] data, long length, long previousCrc32)
{    //long crc = ~previousCrc32; // same as previousCrc32 ^ 0xFFFFFFFF
    //force long to unsigned integer below
    long crc = Complement(previousCrc32);
    /// look-up table for half-byte, same as crc32Lookup[0][16*i]
    final long Crc32Lookup16[] = new long[]
    {
    0x00000000,0x1DB71064,0x3B6E20C8,0x26D930AC,0x76DC4190,0x6B6B51F4,0x4DB26158,0x5005713C,
    0xEDB88320,0xF00F9344,0xD6D6A3E8,0xCB61B38C,0x9B64C2B0,0x86D3D2D4,0xA00AE278,0xBDBDF21C
    };

    for (int i=0; i < data.length; i++)
    {
       long temp1 = (crc ^  (data[i])      ) & 0x0F;
       //System.out.format("temp 1 is %d\n", temp1);
       crc = (Crc32Lookup16[LongToInt(temp1)] ^ (crc >>> 4));
       long temp2 = (crc ^ (data[i] >>> 4)) & 0x0F;
       //System.out.format("temp 2 is %d\n", temp2);
       crc = (Crc32Lookup16[LongToInt(temp2)] ^ (crc >>> 4));
    }
    return Complement(crc); //return crc ^ 0xFFFFFFFF;
}


     public static void main(String []args){
    System.out.println("Hello World");
    final String str = "Hello World";
    byte[] test_string = str.getBytes();
    long test_crc32_bw = Crc32Bitwise(test_string,test_string.length,0);
    System.out.format("%d\n",LongToInt(test_crc32_bw));
    long test_crc32_hb = Crc32HalfByte(test_string,test_string.length,0);
    System.out.format("%d\n",LongToInt(test_crc32_hb));
     }
}

結果

$javac CRC32.java
$java -Xmx128M -Xms16M CRC32
Hello World
1243066710
951982353

為什么我得到不同的結果? 我是否在轉換中缺少某些內容,例如,長整型或移位運算符是錯誤的? 謝謝。

好的,我發現了問題-這是類型轉換問題。 我改變了以下

   crc = (Crc32Lookup16[LongToInt(temp1)] ^ (crc >>> 4));
   //...
   crc = (Crc32Lookup16[LongToInt(temp2)] ^ (crc >>> 4));

   crc = (Crc32Lookup16[LongToInt(temp1)] ^ ((int)crc >>> 4));
   //...
   crc = (Crc32Lookup16[LongToInt(temp2)] ^ ((int)crc >>> 4));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM