从执行USD AT命令,我得到以下回复:
00520030002E00300030002000610069007200740069006D0065002C0020003000200053004D005300200061006E0064002000300020004D00420020006F006600200064006100740061002E0020004400690061006C0020002A003100340031002A0031002300200066006F0072002000640065007400610069006C0073002E00200057006F005700210020005500730065002000520037002000610069007200740069006D006500200074006F00200067006500740020005200350035002B00310030004D0042002E004400690061006C0020002A003100330030002A0035003000310023
产生:
' 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 o r d e t a i l s。哇 ! 使用R 5 5 + 1 0 M B R 7 a。 D i a l * 1 3 0 * 5 0 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.Dial * 130 * 501#'
所以我的问题:我不知道为什么会这样做,这是一个我不知道的标准吗?
答案 0 :(得分:1)
您似乎有UTF-16 - 编码数据,采用大端顺序,每个字符编码使用2个字节。对于Latin-1范围内的任何内容(Unicode代码点U + 0000到U + 00FF),最重要的字节始终为00;您的样本数据仅包含ASCII范围内的字符,但我并不指望总是如此。
您可以直接对此进行解码,而无需使用>>> 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
在大多数情况下,UTF-16编码的数据在开始时包含Byte Order Mark (BOM),它实际上只是U+FEFF ZERO WIDTH NO-BREAK SPACE字符,它告诉解码器在解码时使用的字节顺序。打印时,角色基本上是不可见的。
您可能在此省略了它,但如果您的数据流以字节FE FF开头,则肯定会确认您拥有大端UTF-16数据。如果流以FF FE开始,那么你有小 -endian UTF-16(字节顺序交换),并且在这里也将你的样本切割到错误的边界。
如果有BOM,那么您不必手动指定字节顺序;用>>> ('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#'
解码就足够了:
{{1}}
答案 1 :(得分:0)
>>> 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#