您的位置:首页 > 编程语言 > Java开发

java解码PDU短信

2017-08-21 11:36 204 查看
一共3个问题:1.PDU短信是什么;2.为什么要用pdu;3.如何用java解码

1.pdu短信是什么?

短信的一种方式,被所有手机支持,可以使用任何字符集,这也是手机默认的编码方式;
PDU相当于一个数据包,它由构成消息(SMS)的信息组成。作为一种数据单元,它必须包含源/目的地址、保护(有效)时间、数据格式、协议类型和正文,正文长度可达140字节,它们都以十六进制表示。PDU结构根据短消息由移动终端发起或以移动终端为目的而不同。每条消息可以发送140个字节,由于本系统中最长的数据串没有超过140个字节,因此数据均可以用一条消息来发送;

其中又分7bit-160,8bit-140,16bit-70的方式,我们中文用16bit70的方式。

范例
发送:SMSC号码是+8613800250500,对方号码是13851872468,消息内容是“Hello!”。
从手机发出的PDU串可以是08 91 68 31 08 20 05 05 F0 11 00 0D 91 68 31 58 81 27 64 F8 00 00 00 06 C8 32 9B FD 0E 01 

对照规范,具体分析:  
08  SMSC地址信息的长度     共8个八位字节(包括91)
91  SMSC地址格式(TON/NPI)   用国际格式号码(在前面加‘+’) 
68 31 08 20 05 05 F0  SMSC地址   8613800250500,补‘F’凑成偶数个 
11  基本参数(TP-MTI/VFP)   发送,TP-VP用相对格式 
00  消息基准值(TP-MR)  0
0D  目标地址数字个数  共13个十进制数(不包括91和‘F’)
91  目标地址格式(TON/NPI)   用国际格式号码(在前面加‘+’) 
68 31 58 81 27 64 F8  目标地址(TP-DA)   8613851872468,补‘F’凑成偶数个,BCD编码方式,低位-高位方式
 
00   协议标识(TP-PID)  是普通GSM类型,点到点方式 
00   用户信息编码方式(TP-DCS)   7-bit编码
 
00   有效期(TP-VP)   5分钟
 
06   用户信息长度(TP-UDL)    实际长度6个字节 

C8 32 9B FD 0E 01   用户信息(TP-UD)    “Hello!”

 

0891683108100005F0 31 00 0B 81 3129503323F1 00 08 A8 0C 4F6060F3776189C94E865427

分析一下
分段 
 含义 
 说明
 
08 
 SMSC地址信息的长度 
 共8个八位字节(包括91)
 
91 
 SMSC地址格式(TON/NPI) 
 用国际格式号码(在前面加‘+’),81表示没有+
 
683108100005F0 
 SMSC地址 
 8613800100500,补‘F’凑成偶数个bcd编码
31 
 基本参数(TP-MTI/VFP) 
 发送,TP-VP用相对格式。标志
 
00 
 消息基准值(TP-MR) 
 0
 
0D 
 目标地址数字个数 
 共13个十进制数(不包括91和‘F’)
 
81 
 目标地址格式(TON/NPI) 
 用国际格式号码(在前面加‘+’),81表示没有‘+’
 
3129503323F1 
 目标地址(TP-DA) 
 8613851872468,补‘F’凑成偶数个,BCD编码方式,低位-高位方式
 
00 
 协议标识(TP-PID) 
 是普通GSM类型,点到点方式
 
08 
 用户信息编码方式(TP-DCS) 
 16-bit编码,UCS2编码
 
A8 
 有效期(TP-VP) 
 2天
 
0C
 用户信息长度(TP-UDL) 
 实际长度12个字节
 
4F6060F3776189C94E865427 
 用户信息(TP-UD) 
 “你睡觉了吧!”

2.为什么要用pdu?
被所有手机支持
通用的十六进制

3.如何用java解码?
暂时只展示了7-bit和16bit(UCS2,UCS2编码用于发送Unicode字符)的解码代码

7-bit
public static String hexString7ToString(String s){
if (StringUtils.isEmpty(s))
throw new IllegalArgumentException("this hexString must not be empty");
byte[] dataArray = hexStr2ByteArray(s);
String str = decode7bit(dataArray);
return  str;

}

/**
* 7-bit解码
* @param data
* @return
*/
public static String decode7bit(byte[] d){
byte[] other_mask ={(byte) 0x80,(byte) 0xc0,(byte) 0xe0,(byte) 0xf0,(byte) 0xf8,(byte) 0xfc,(byte) 0xfe};
byte[] my_mask = {0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01};
byte other = 0;
byte temp = 0;
StringBuffer sb = new StringBuffer();
for(int i=0;i<d.length;i++){
int index = i%7;
temp = d[i];
//得到我的数据
d[i] = (byte) (d[i]&my_mask[index]);
d[i] = (byte) (d[i] << index);
if(index != 0){
d[i] = (byte) (d[i]&other_mask[7-index]);
other = (byte) (other>>(8-index));
other = (byte) (other&my_mask[7-index]);
d[i] = (byte) (d[i] | other);
}
//先把下一个数据信息拿走
other = (byte) (temp&other_mask[index]);
sb.append((char)d[i]);
if(index == 6){
other = (byte) (other>>1);
other = (byte) (other & 0x7f);
sb.append((char)other);
}
}
return sb.toString();
}

public static byte[] hexStr2ByteArray(String hexString) {
//TODO Hex.decode(hexString);
if (StringUtils.isEmpty(hexString))
throw new IllegalArgumentException("this hexString must not be empty");

hexString = hexString.toLowerCase();
final byte[] byteArray = new byte[hexString.length() / 2];
int k = 0;
for (int i = 0; i < byteArray.length; i++) {
//因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
//将hex 转换成byte   "&" 操作为了防止负数的自动扩展
// hex转换成byte 其实只占用了4位,然后把高位进行右移四位
// 然后“|”操作  低四位 就能得到 两个 16进制数转换成一个byte.
//
byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
byteArray[i] = (byte) (high << 4 | low);
k += 2;
}
//		System.out.println("16进制明文字符串转成16进制字节数组:"+byteArray);


16-bit
public static String DecodeUCS2(String src) {
byte[] bytes = new byte[src.length() / 2];

for (int i = 0; i < src.length(); i += 2) {
try {
bytes[i / 2] = (byte) (Integer
.parseInt(src.substring(i, i + 2), 16));
} catch (Exception e) {
System.out.println("异常字符:"+src.substring(i, i + 2));
}
}
String reValue="";
try {
reValue = new String(bytes, "UTF-16BE");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return reValue;

}


其他参考链接: http://www.cnblogs.com/heiyue/p/7008499.html http://blog.csdn.net/yangfeiyang/article/details/5526649
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: