[英]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.