Python 将40字节的二进制数据读取为ascii文本

Python 将40字节的二进制数据读取为ascii文本,python,Python,我有一些二进制数据,在十六进制编辑器中,它看起来像: s、 o.m.e.d.a.t.a 每个字母之间都有这些点 当我用filehandle.read读取时(40) 它显示了这些点 我知道点不应该在那里,有没有办法用struct解包一些40字节长的ascii数据 我尝试了“4S”和“S”,但是它显示了奇怪的数据,或者只解包1个字符而不是40个。 < P>快速和肮脏的解决方案是使用 S[[:2 ] < /COD> >其中 s>代码>是80个字节字节串,其中你只考虑备用字节。根据@fadden的评论,

我有一些二进制数据,在十六进制编辑器中,它看起来像: s、 o.m.e.d.a.t.a

每个字母之间都有这些点

当我用filehandle.read读取时(40) 它显示了这些点

我知道点不应该在那里,有没有办法用struct解包一些40字节长的ascii数据


我尝试了“4S”和“S”,但是它显示了奇怪的数据,或者只解包1个字符而不是40个。

< P>快速和肮脏的解决方案是使用<代码> S[[:2 ] < /COD> >其中<代码> s>代码>是80个字节字节串,其中你只考虑备用字节。根据@fadden的评论,“清洁:解决方案可能是将数据读入
UTF-16
(然后
。将其编码为ASCII等),但如果Q&D满足您的需要,它可能会更简单、更快(如果原始数据中的字符不在最低256个范围内,Q&D方法将给出奇怪的结果,而正确的方法将引发异常——哪种处理更好取决于您的应用程序…。

如果您的第一个字节是ASCII字符(如您的示例所示)第二个字节是“\x00”,那么数据可能编码为UTF-16LE

但是,如果您向我们展示了文件前几个字节中的确切内容,这将是一个好主意。请执行以下操作:

python -c "print(repr(open('myfile.txt', 'rb').read(20)))"
并编辑您的问题以显示结果。如果任何文本是机密的,请在编辑时保留其含义

我们特别感兴趣的是,它是否以UTF-16 BOM开始(
'\xff\xfe'
'\xfe\xff'

作为背景,您在什么平台(Windows或Linux)上?是什么生成了该文件

更新我对您的陈述感到有点困惑““我尝试了'40s'和's',但它显示了奇怪的数据,或者只解压了1个字符而不是40个。”“检查以下示例:

>>> data = "q\x00w\x00"
>>> unpack("4s", data)
('q\x00w\x00',) # weird? it's effectively tuple([data])
>>> unpack("s", data)
# doesn't produce a string of length 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
struct.error: unpack requires a string argument of length 1
>>> unpack("ssss", data)
('q', '\x00', 'w', '\x00') # this == tuple(data)
>>>
数据=“q\x00w\x00” >>>拆包(“4s”,数据) ('q\x00w\x00',)#奇怪?它实际上是元组([数据]) >>>解包(“s”,数据) #不会生成长度为1的字符串 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 struct.error:解包需要长度为1的字符串参数 >>>解包(“ssss”,数据) ('q','\x00','w','\x00')#this==元组(数据) >>>

@pxh评论道:“您只得到一个字符,因为这些点被读取为ASCII NUL(并因此终止字符串)。”我非常怀疑@pxh是否能够证明struct.unpack对
“s”
格式的使用在任何方面都取决于数据中的单个字节值,无论
NUL
“\x00”
)或其他任何内容。

我正在使用python读取二进制数据:

val = f.read(1)
val = struct.unpack( 'c' , val )
一个字节一个字节地读我需要的东西。 对于40字节的结构,我将

val = f.read(40)
val = struct.unpack( '40c' , val )

点是十六进制编辑器中的0x00吗?我想知道这是否是UTF-16文本,您可以通过适当的文本转换来读取。是的--这里的问题是您正在处理某种非ASCII数据,最有可能是UTF-16。您只得到一个字符,因为这些点被读取为ASCII NUL(因此终止字符串)。快速和肮脏是可怕的!整洁。虽然它是utf-16是有意义的。。谢谢两个:)-1首先,OP有文本问题,而不是二进制数据。其次,
val=struct.unpack('40c',val)
只是编写
元组(val)的一个很长的过程
而且容易出错——您需要确保在读取和解包时使用相同的长度(例如:40)。