从手机发出的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)
“你睡觉了吧!”
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>(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);
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;
}