2010-01-21 51 views
2

如何將這段C代碼翻譯成Python> = 2.6?Python中無符號長溢出字節的總和

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)) 

如果您需要環繞在溢出,只需把你的總和模MAX_LONG末不起作用

+1

'f.read()'將'f'的內容作爲字符串加載。你需要將它轉換成'sum'的'int'列表/數組才能工作。 – MAK 2010-01-21 21:48:16

+1

這是什麼 array.array('B',m) 沒有? – lclevy 2010-01-21 21:57:30

+0

是的,array.array('B',m)將它轉換爲無符號字符的列表(例如array.array('b',m)將其轉換爲帶符號的字符) – Khelben 2010-01-21 22:12:52

回答

3

+0

對不起,它不起作用。即使「對於c in m:cchk =(cchk + ord(c))&0xffffffff」也不起作用,並且給出與「sum(array('B',m))方法相同的錯誤結果」 – lclevy 2010-01-21 22:00:31

+1

什麼是壞結果「是這樣嗎?我們應該猜猜你在想什麼嗎? – 2010-01-21 22:02:24

0

正如我在我的評論中提到的,您需要將字符串轉換爲int s的list。 這可能是你想要什麼:

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

ord函數返回對應於一個字符的ASCII int

0

我試過你的代碼,似乎是工作(它打開二進制數據,將其轉換爲無符號字符列表並添加所有)。

你的問題是什麼?可能是溢出問題?也許長度有問題?你如何保存文件? 對不起,但有了這些信息,我們只能猜測!

代碼並不等同,因爲Python代碼似乎處理文件,而C代碼似乎是處理內存數組。

2

直接,Python的翻譯:

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

你真的需要舉一個例子輸入你所期望的輸出是什麼。任何使用Python最新版本的代碼都會從每個字節中提取一個範圍(256)內的整數,並將這些整數相加,最後total &= 0xFFFFFFFF應該完成這項工作(假設您的unsigned long的寬度爲32位)。

請注意,如果您的文件大小小於大約16MB,則最後一步(&=)毫無意義...它不會溢出; 16843009 * 255 < = 0xFFFFFFFF <(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代碼都應該是獨立運行的,並且應該包括打印字節數組的大小。

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

我想這是因爲在這裏字節在蟒蛇解釋爲簽名,而不是無符號(如在C)...

更新:

即使

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

不工作,並再次給504a022a

+0

該文件是二進制文件還是帶有數字的文本文件?如果它是一個文本文件,您應該向我們展示一些數據。你還應該告訴我們你如何讀取C中的數據。最後,爲什麼要創建一個新的ID?並請編輯您的原始問題。 – 2010-01-22 09:57:21

+0

您沒有仔細閱讀答覆 - 他們都沒有將Python字節視爲已簽名。 – 2010-01-22 11:10:02

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,我校驗包含解密數據的給定存儲區域,在那裏解密已經在我的Python實現已經完成「到位」

,解密在另一個緩衝區中完成,並且我仍然對加密區域進行校驗。

因爲我是一名Python初學者,所以我專注於這一點:糟糕的軌道。 我踢我的屁股二十次.....

抱歉的愚蠢問題,再次感謝您的親切幫助!

相關問題