将crc代码从C转换为Java会产生意外结果 [英] Converting crc code from C to Java yields unexpected results

查看:104
本文介绍了将crc代码从C转换为Java会产生意外结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将CRC C代码转换为Java,但没有得到预期的结果。这就是我到目前为止所拥有的...

I am trying to convert CRC C code to Java but I am not getting expected results. Here is what I have so far...

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

为什么会得到不同的结果?我在转换中是否缺少某些东西,例如多久要int或shift运算符是错误的?谢谢。

Why am I getting different results? Am I missing something in conversion e.g. long to int or shift operator is wrong? Thanks.

推荐答案

好,我发现了问题-这是类型转换问题。我更改了以下

Ok I found the problem - It was type casting issue. I changed the following

   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));

这篇关于将crc代码从C转换为Java会产生意外结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆