python中带无符号长溢出的字节总和

时间:2010-01-21 21:37:34

标签: python overflow sum byte

如何将这段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 个答案:

答案 0 :(得分:3)

如果你需要在溢出时回头看,最后只需将你的总和模数MAX_LONG。

答案 1 :(得分:2)

直接的Pythonic翻译:

def memSum(data):
    return sum(ord(c) for c in data) & 0xFFFFFFFF

答案 2 :(得分:0)

正如我在评论中提到的,您需要将字符串转换为list int s。 这可能是你想要的:

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

ord函数返回与字符对应的ascii int

答案 3 :(得分:0)

我已经尝试了你的代码,似乎正在工作(它以二进制打开数据,将其转换为unsigned char列表并添加所有内容)。

你有什么问题?可能是溢出问题?也许长度有问题?你是如何保存文件的? 对不起,但有了这些信息,我们只能猜测!

代码不等同,因为Python代码似乎处理文件而C代码似乎处理内存数组。

答案 4 :(得分:0)

您确实需要提供示例输入以及您对输出的期望。任何使用最新版本Python的代码,从每个字节中提取范围(256)的整数,对这些整数求和,最后total &= 0xFFFFFFFF应该完成这项工作(假设你的unsigned long是32位宽)。

请注意,如果您的文件大小小于约16MB,则最后一步(&=)毫无意义...它不会溢出; 16843009 * 255&lt; = 0xFFFFFFFF&lt; (16843009 + 1)* 255

这意味着如果您的测试文件小于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代码都应该是独立运行的,并且应该包括打印要求的字节数组的大小。

答案 5 :(得分:0)

首先,谢谢大家的帮助

我已经成功编写了C实现,并测试了20多个不同文件的校验和功能。然后将计算出的校验和的2补码与文件的校验和进行比较。它在C中完美地工作,如提到的:使用unsigned char和unsigned long。

总和的正确值是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中的字节解释为signed而不是unsigned(就像在C中一样)...

更新

甚至

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

不起作用,再次给出504a022a

答案 6 :(得分:0)

解决:我的错误,抱歉

#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中,i校验一个包含解密数据的给定内存区域,其中解密已经“就地”完成了

在我的python实现中,解密是在另一个缓冲区完成的,我仍然会校验加密区域。

因为我是python的初学者,所以我专注于这一点:糟糕的轨道。 我踢了我的屁股二十次.....

抱歉这个愚蠢的问题,再次感谢你的帮助!!!