2012-05-06 109 views
2

我這裏有一個小的腳本,我需要一些幫助:麻煩固定binascii奇數長度字符串問題

for song in songs: 
    slash = song.rindex('\\') 
    songbyte = slash + 2 
    if len(str(songbyte)) < 2: 
    #if songbyte < 10: 
     songbyte = "0" + str(songbyte) 
     f.write(binascii.a2b_hex(songbyte)) 
    else: 
     f.write(binascii.a2b_hex("{0:x}".format(songbyte))) 
f.close() 
return 

首先,我試圖寫一個播放列表。出於測試目的,我正在寫一個包含49首歌曲的歌曲 - 歌曲是我正在迭代的包含49首歌曲的列表。

我需要編寫songbyte - 它是一個介於8到72之間的值。目前我只是迭代並確保它對每個字節都有正確的值(這是已知正確播放列表的副本,通過diff和十六進制編輯器進行非常重要)。

我的問題是該行

print(binascii.a2b_hex("{0:x}".format(songbyte))) 

拋出 「類型錯誤:奇數長度字符串」。現在,這足夠描述了。通過調查,我已經確定,當它發生錯誤時,字節的值是8.然而,沒有任何意義的是,這個錯誤發生在列表中的37首歌曲中,並且大部分其他歌曲的歌詞也是8 - 和我的len(str(songbyte))< 2檢查哪個增加了一個0 - 但奇怪的是這個沒有。

雖然我希望我不確定這是否有足夠的信息來幫助我解決問題,儘管我認爲我不能提供整個腳本的完整詳細信息。有沒有另外一種方法可以將songbyte(十六進制)寫入文件?

回答

1

您應該使用struct.pack,這正是爲了這個目的的意思是:

import struct 
for song in songs: 
    slash = song.rindex('\\') 
    songbyte = slash + 2 
    f.write(struct.pack('!B', songbyte)) 

號碼前串"{0:x}"不會插入零的格式,你想要"{0:02x}"

>>> "{0:x}".format(12) 
'c' 
>>> "{0:02x}".format(12) 
'0c' 

儘管如此,使用binascii會導致不必要的複雜和脆弱的代碼。例如,如果數值超過255,它將默默產生超過2個字符。

+0

哇,這工作得非常好,我一定會讀到結構!謝謝。 – src