сумма байтов с длинным беззнаковым переполнением в питоне - PullRequest
2 голосов
/ 22 января 2010

как перевести этот кусок кода C на Python> = 2.6?

unsigned long memSum(unsigned char *p, unsigned long len)
{
   unsigned long i, sum=0;

   for(i=0; i<len; i++) 
      sum = sum + *p++;

   return sum;
}  

конечно

f=open("file_to_sum",'rb')
m = f.read()
f.close()
sum( array.array('B', m) )

не работает

Ответы [ 7 ]

3 голосов
/ 22 января 2010

Если вам нужно обернуться при переполнении, просто возьмите сумму по модулю MAX_LONG в конце.

2 голосов
/ 22 января 2010

Прямой, Pythonic перевод:

def memSum(data):
    return sum(ord(c) for c in data) & 0xFFFFFFFF
0 голосов
/ 22 января 2010

решено: МОЙ ОШИБКА, К сожалению

#include<stdio.h>

unsigned long memSum(unsigned char *p, unsigned long len)
{
   unsigned long i, sum=0;

   for(i=0; i<len; i++) 
      sum = sum + *p++;

   return sum;
}  

#define LEN2SUM (0xa13b10-4)

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

  FILE *f;
  unsigned char *buf;
  unsigned long sum;

  f=fopen("test2.dat", "rb");
  fseek(f, 0x7c+4, SEEK_SET); 

  buf = (unsigned char*)malloc(LEN2SUM);
  fread(buf, sizeof(char), LEN2SUM, f);
  sum = memSum( buf, LEN2SUM);
  printf("0x%08x\n", sum );

  free(buf);  
  fclose(f);


}

и

f = open('test2.dat','rb')
f.seek(0x7c+4)

m = f.read(0xa13b10-4)
print '%x' % ( ( sum(ord(c) for c in m) & 0xFFFFFFFF ) )

дай тот же ответ, хороший

Разница в том, что в C, я проверяю сумму данной области памяти, которая содержит расшифрованные данные, где дешифрование было сделано "на месте"

в моей реализации на python расшифровка выполняется в другом буфере, и я все еще проверяю сумму зашифрованной области.

, так как я начинающий в python, я был сосредоточен на этом: плохой трек. я бью себя по заднице двадцать раз .....

извините за глупый вопрос и еще раз спасибо за вашу помощь !!!

0 голосов
/ 22 января 2010

во-первых, спасибо всем за помощь

Я успешно написал реализацию C и протестировал более 20 различных файлов с функцией контрольной суммы. А затем 2 дополнения вычисленной контрольной суммы сравниваются с контрольной суммой в файле. Он отлично работает в Си, как уже упоминалось: с беззнаковым символом и беззнаковым длинным.

правильное значение суммы - 3da4be70 (из реализации C) из ваших предложений:

print '%x' % ( sum( array.array('B', m[ o2+4:o2+len2 ]) ) )

и

n = map(ord, list(m[ o2+4: o2+len2 ]))
print '%x' % (sum(n))

дать 504a022a

Полагаю, это потому, что байты здесь в python интерпретируются как подписанные, а не как беззнаковые (как в C) ...

обновление:

даже

for i in range(o2+4, o2+len2):
 cchk = ( (cchk + unpack('B', m[i])[0]) & 0xffffffff)
print '%x' % (cchk)

не работает и снова выдает 504a022a

0 голосов
/ 22 января 2010

Вам действительно нужно привести пример ввода и того, что вы ожидаете получить. Любой код, который использует последнюю версию Python, извлекает целое число в диапазоне (256) из каждого байта, суммирует эти целые числа и, наконец, total &= 0xFFFFFFFF должен выполнить свою работу (предполагая, что ваш unsigned long имеет ширину 32 бита).

Обратите внимание, что последний шаг (&=) не имеет смысла, если ваш файл имеет размер менее 16 МБ ... он не переполнится; 16843009 * 255 <= 0xFFFFFFFF <(16843009 + 1) * 255 </p>

Это означает, что если ваш тестовый файл меньше 16843010 байт, у вас должна быть проблема в коде C или в коде Python или обоих.

Вы сказали, что "конечно" этот код:

f=open("file_to_sum",'rb')
m = f.read()
f.close()
sum( array.array('B', m) )

"не работает". Работает ли, если вы замените последнюю строку на

print sum( array.array('B', m) )

Если ничего из вышеперечисленного не поможет, и вам нужны разумные ответы, а не догадки, укажите пример ввода, ожидаемый вывод, код C, вывод C, код Python, вывод Python. И код C, и код Python должны быть автономно управляемыми и должны включать печать размера байтового массива, суммируемого.

0 голосов
/ 22 января 2010

Я попробовал ваш код и, похоже, работает (он открывает данные в двоичном виде, преобразует их в список неподписанных символов и добавляет все).

В чем ваша проблема? Может быть проблема переполнения? Может быть, есть проблема с длиной? Как вы сохраняете файл? Извините, но с этой информацией мы можем только догадываться!

Код не эквивалентен, так как код Python, похоже, имеет дело с файлами, а код C, похоже, имеет дело с массивом памяти.

0 голосов
/ 22 января 2010

Как я уже упоминал в своем комментарии, вам нужно преобразовать строку в list из int s. Это, вероятно, то, что вы хотите:

f=open("infile.txt",'rb')
m=f.read()
f.close()
m=map(ord,list(m))
print sum(m)

Функция ord возвращает ascii int, соответствующий символу.

...