2012-08-28 2 views
0

Я пытаюсь вычислить контрольную сумму файла Sega Genesis rom в Java. Для этого я хочу перенести код, отрезанный от C на Java:Бит-манипуляция C-источник в Java

static uint16 getchecksum(uint8 *rom, int length) 
{ 
    int i; 
    uint16 checksum = 0; 

    for (i = 0; i < length; i += 2) 
    { 
    checksum += ((rom[i] << 8) + rom[i + 1]); 
    } 

    return checksum; 
} 

Я понимаю, что делает код. Он суммирует все 16-битные числа (в сочетании с двумя 8-битными). Но что я не понял, что происходит с переполнением uint16 и как это переносится на Java-код?

Edit: Этот код, кажется, работает, спасибо:

int calculatedChecksum = 0; 
int bufferi1=0; 
int bufferi2=0; 
bs = new BufferedInputStream(new FileInputStream(this.file)); 

bufferi1 = bs.read(); 
bufferi2 = bs.read(); 
while(bufferi1 != -1 && bufferi2 != -1){ 
    calculatedChecksum += (bufferi1*256 + bufferi2); 
    calculatedChecksum = calculatedChecksum % 0x10000; 
    bufferi1 = bs.read(); 
    bufferi2 = bs.read(); 
} 
+1

Вы можете взять больший целочисленный тип и уменьшить по модулю '0x10000' в каждом раунде цикла. –

+1

Этот код точно такой же в Java. Просто используйте 'unsigned byte []' для указателя 'uint8_t' и' unsigned short' для контрольной суммы. Все остальное - то же самое. –

+0

@JasonCoco: Java не имеет типа unsigned short. –

ответ

0

Вы хотите сложение по модулю 2 , который вы можете просто заклинание вручную:

checksum = (checksum + ((rom[i] << 8) + rom[i + 1])) % 0x10000; 
//             ^^^^^^^^^ 
1

Проще говоря, переполнение теряется. Более правильный подход (imho) заключается в использовании uint32 для суммирования, а затем у вас есть сумма в младших 16 бит и переполнение в верхних 16 битах.

1
static int checksum(final InputStream in) throws IOException { 
    short v = 0; 
    int c; 
    while ((c = in.read()) >= 0) { 
    v += (c << 8) | in.read(); 
    } 
    return v & 0xffff; 
} 

Это должно работать одинаково; используя & 0xffff, мы получаем для обработки значение в v, как если бы оно было без знака все время, так как арифметическое переполнение идентично w.r.t. биты.

+0

Хорошо, это и 0xffff интересно. У вас больше информации об этом? – Johni

+0

@Johni обрабатывает все 16 бит 'short' как' int'. – oldrinb

+0

Да, но что вызывает подобное поведение? Так как бисовое «и» не меняет самих данных. – Johni

Смежные вопросы