Python 2.7,AT命令响应,奇怪的十六进制

Python 2.7,AT命令响应,奇怪的十六进制,python,python-2.7,pyserial,at-command,Python,Python 2.7,Pyserial,At Command,通过执行USD AT命令,我得到以下响应: 00520300002E03002000610069007200740006D0065002C00200030000200053004D005300200061006E006400200020004D04200200006F006600060006000640061006006200004400690061006C00200002A00310030030066006F007200640065007400610069006C0073002E0200057

通过执行USD AT命令,我得到以下响应:

00520300002E03002000610069007200740006D0065002C00200030000200053004D005300200061006E006400200020004D04200200006F006600060006000640061006006200004400690061006C00200002A00310030030066006F007200640065007400610069006C0073002E020005700006F00570070070070070055007300650200006203003003507007007006100070006700700700700700700070006D002070006F0020000670065007400200005200350035002B0031003000400042002E004400690061006C00200002A003100330002A00035003000310002A00310023

产生:

R 0。0 0 a i r t i m e,0 S m S a n d 0 m B o f d 一点也不。D i a l*1 4 1*1#f r D e t a i l。哇! U s e R 7 a i R t i e g t R 5 5+10 m B。我要一个l *130*50 1#'

运行后:

ascii = rawHex.decode("hex")
我发现在每个“有效”十六进制数字后面还有一个空字符。因此,它生产的不是52台,而是5200台

我确实通过以下操作成功删除了每个有效十六进制数字后的00:

rawHex = ''.join( [ rawHex[i:i+2] for i in range(2,len(rawHex),4)] )
ascii = rawHex.decode("hex")
这将产生正确的结果:

'R0.00广播时间,0条短信和0 MB数据。详情请拨打*141*1。哇! 使用R7广播时间获取R55+10MB。拨号*130*501#'

所以我的问题是:我不知道它为什么会这样做,这是一个我还不知道的标准吗?

您似乎已经以大端顺序对数据进行了编码,每个字符编码使用2个字节。对于拉丁-1范围内的任何内容(Unicode代码点U+0000到U+00FF),最高有效字节始终为00;您的示例数据仅由ASCII范围内的字符组成,但我不认为总是这样

>>> print hex_string.decode('hex').decode('utf-16be')
R0.00 airtime, 0 SMS and 0 MB of data. Dial *141*1# for details. WoW! Use R7 airtime to get R55+10MB.Dial *130*501#
您可以使用
utf-16-be
编解码器直接解码,而无需删除空字节:

>>> rawhex = '00520030002E00300030002000610069007200740069006D0065002C0020003000200053004D005300200061006E0064002000300020004D00420020006F006600200064006100740061002E0020004400690061006C0020002A003100340031002A0031002300200066006F0072002000640065007400610069006C0073002E00200057006F005700210020005500730065002000520037002000610069007200740069006D006500200074006F00200067006500740020005200350035002B00310030004D0042002E004400690061006C0020002A003100330030002A0035003000310023'
>>> rawhex.decode('hex')
'\x00R\x000\x00.\x000\x000\x00 \x00a\x00i\x00r\x00t\x00i\x00m\x00e\x00,\x00 \x000\x00 \x00S\x00M\x00S\x00 \x00a\x00n\x00d\x00 \x000\x00 \x00M\x00B\x00 \x00o\x00f\x00 \x00d\x00a\x00t\x00a\x00.\x00 \x00D\x00i\x00a\x00l\x00 \x00*\x001\x004\x001\x00*\x001\x00#\x00 \x00f\x00o\x00r\x00 \x00d\x00e\x00t\x00a\x00i\x00l\x00s\x00.\x00 \x00W\x00o\x00W\x00!\x00 \x00U\x00s\x00e\x00 \x00R\x007\x00 \x00a\x00i\x00r\x00t\x00i\x00m\x00e\x00 \x00t\x00o\x00 \x00g\x00e\x00t\x00 \x00R\x005\x005\x00+\x001\x000\x00M\x00B\x00.\x00D\x00i\x00a\x00l\x00 \x00*\x001\x003\x000\x00*\x005\x000\x001\x00#'
>>> rawhex.decode('hex').decode('utf-16-be')
u'R0.00 airtime, 0 SMS and 0 MB of data. Dial *141*1# for details. WoW! Use R7 airtime to get R55+10MB.Dial *130*501#'
在大多数情况下,UTF-16编码的数据在开头包含一个字符,它实际上只是一个字符,它告诉解码器在解码时使用什么字节顺序。打印时,字符基本上是不可见的

您可能在这里忽略了它,但若您的数据流以字节FE FF开始,那个么这肯定会确认您拥有big-endian UTF-16数据。如果流以FF FE开始,那么您有一个小的endian UTF-16(字节顺序交换),并且在错误的边界处剪切您的样本

如果有BOM,则不必手动指定字节顺序;使用utf-16进行解码就足够了:

>>> ('FEFF' + rawhex).decode('hex').decode('utf-16')
u'R0.00 airtime, 0 SMS and 0 MB of data. Dial *141*1# for details. WoW! Use R7 airtime to get R55+10MB.Dial *130*501#'

连接(CHR(int(f[i* 4(:i 4)+4),16))对于i在范围(LeN(f)/4))< /Cord> f是您的字符串。在发布和等待答案之后,我认为它可能是UTF 16,但是我甚至没有考虑过大的和小的字节序格式。但我不知道物料清单。不,一开始就没有包括在内。谢谢你这个答案值得我一半的声誉(又名赏金)哈哈