PDU Mode被所有手机支持,可以使用任何字符集,这也是手机默认的编码方式。网上C语言的编码实例很多,基于python写的不多,特基于python3.7实现AT指令发送短信,以及PDU编码,串口操作。
PDU编码规则网上资源很多,在线编码地址:
在线PDU
可以用于比对调试。
直接上代码。
# 处理收件人 “8613800280500” -> “683108200805F0”
def deal_iphonenum(demo): # 收件人 "8613800280500" -> "683108200805F0"
if len(demo) % 2 != 0:
demo = demo + "F"
else:
demo = demo
listdemo = []
for x in range(len(demo)): listdemo.append(demo[x])
qi = listdemo[::2]
ou = listdemo[1::2]
end = []
if len(qi) == len(ou): # 奇偶互换
for i in range(len(qi)):
end.append(ou[i])
end.append(qi[i])
return "".join(end)
中心号码 “8613800280500” -># “0891683108200805F0”
def deal_center_iphone_num(demo):
# 中心号码 "8613800280500" -># "0891683108200805F0"
if len(demo) % 2 != 0:
demo = demo + "F"
else:
demo = demo
listdemo = []
for x in range(len(demo)): listdemo.append(demo[x])
qi = listdemo[::2]
ou = listdemo[1::2]
end = []
if len(qi) == len(ou): # 奇偶互换
for i in range(len(qi)):
end.append(ou[i])
end.append(qi[i])
return "0891"+"".join(end)
编码短信内容:
def expand_to_16(ucode): #ascii字符--16-bit编码
for i in range(len(ucode)):
if (len(ucode[i])==4):
ucode[i] = ucode[i][0:2]+"00" + ucode[i][2:]
return ucode
def msg_ucs2_encode(src):
# 7-bit编码 用于发送普通的ASCII字符,
# 8-bit编码 通常用于发送数据消息,
# UCS2编码 用于发送Unicode字符。
# UCS2编码 中文:你好-> 4f60597d
# 7-bit hello -> 00680065006c006c006f 英文-> ascii -> 转hex,16进制。补0
# 8-bit 1234 - > 0031003200330034
decoder = codecs.getdecoder("utf-8")
ucs2 = decoder(src.encode())
src_len = len(ucs2[0])
ucode = []
result = ""
for i in range(src_len):
ucode.append(hex(ord(ucs2[0][i])))
ucode = expand_to_16(ucode)
for item in ucode:
result = result+item[2:]
return result
‘’’ 产生PDU 编码’’’
def creatr_Pdu(des, smsc, content):
# 收件人 中心号码 内容
result = ""
type_of_address = "91" # 国际91,中国小灵通“91”
tp_mti = "01" #
tp_mr = "00" #
tp_pid = "00" # 默认为普通GSM类型,即点到点方式
des_len = "0d" # 目标地址数字个数 共13个十进制数(不包括91和‘F’)
alphabet_size = "08" # 默认用16-bit(7/8/16)编码
result += deal_center_iphone_num(smsc) # 加中心站号码
result += tp_mti
result += tp_mr
result += des_len
result += type_of_address
des = deal_iphonenum(des) # 加收件人号码
result += des
result += tp_pid
result += alphabet_size
# logger.info("con_len:"+(hex(int(len(content) / 2))[2:]).zfill(2))
result += (hex(int(len(content) / 2))[2:]).zfill(2) # !转16进制去除0x 以后补0 0xE->E->0E
result += content
return result.upper()
测试一下:
rev_iphone = "8615928999999"
center_iphone = "8613800280500" # 成都中心号码
masg_content = "坝上雨量缺数,超过2分钟,水位:422.0m/s,最新来数时间:2021-04-15 08:00:00"
masg_content = "1234"
logger.info(creatr_Pdu(rev_iphone, center_iphone