我正在尝试将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
为什么我会得到不同的结果?我在转换中遗漏了什么long to int或shift运算符是错误的?感谢。