2012-05-06 78 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