用Java实现PDU编码

来源:互联网 发布:点对点软件 编辑:程序博客网 时间:2024/05/21 06:50
1.发英文 

发英文时可以进行7bit编码或8bit编码.因为英文和数字等小于128的Ascii码,高位为0,所以,我们可以把最高位也利用起来,去掉最高位的0,然后,每个字节的位以次向前移动,这样一条短信就可以发最多160个字符。因为GSM协议规定短信最多是140个字节,这样的话总共是140×8=1120位,如果我们每个字节只占7位的话,那么就可以容下:1120/7=160个字符。 

当然也可以用UCS2(也就是UTF-16,每个字符占两个字节),这样的话,发送只能发送最多有70个英文字符 

2.发中文 

发送中文时,必须用UCS2进行编码,最多可以发140/2=70个汉字。 

接收到短消息之后,按编码方式进行解码就行了。 

3.参考源代码: 



package com.gftech.common; 

public class PduPack ...{ 
// 短消息中心号长度 
private String smscLen; 

private String smscFormat; 

// 短消息中心号 
private String smsc; 

// 源地址长度 
private int addrLen; 

private String addrFormat; 

// 源地址 
private String addr; 

// 短消息内容编码方式,tp_dcs 
private String msgCoding; 

// 时间戳,tp_scts 
// private String timestamp; 

private int msgLen; 

// 短消息内容,tp_ud 
private String msgContent; 

public PduPack() ...{ 
  smscLen = "08"; 
  smscFormat = "91"; 
  addrLen = 13; 
  addrFormat = "91"; 



public PduPack(String src) ...{ 

  if (src != null && src.length() > 44) ...{ 
   String temp = src.substring(4, 18); 
   smsc = GFString.interChange(temp); 
   if (smsc != null && smsc.length() > 1)...{ 
    smsc = smsc.substring(0, smsc.length() - 1); 
    if(smsc.length()==13) 
     smsc=smsc.substring(2); 
   } 

   temp = src.substring(20, 22); 
   addrLen = Integer.parseInt(temp, 16); 
   if (addrLen % 2 == 0) 
    temp = src.substring(24, 24 + addrLen); 
   else 
    temp = src.substring(24, 24 + addrLen + 1); 
   addr = GFString.interChange(temp); 
   // 去掉为补齐为偶数加上的那一位 
   if (addr != null && addr.length() % 2 == 0) ...{ 
    addr = addr.substring(0, addr.length() - 1); 
    if (addr.length() == 13)// 如果前面有86,去掉它 
     addr = addr.substring(2); 
   } 
   if (addrLen % 2 == 0) ...{ 
    msgCoding = src.substring(24 + addrLen + 2, 24 + addrLen + 4); 
    temp = src.substring(24 + addrLen + 4 + 16); 
   } else ...{ 
    msgCoding = src.substring(24 + addrLen + 3, 24 + addrLen + 5); 
    temp = src.substring(24 + addrLen + 5 + 16); 
   } 
   if (msgCoding.equals("08")) 
    msgContent = GFString.unicode2gb(temp); 
   else 
    msgContent = GFString.decode7bit(temp); 

  } 


public void setSmsc(String s) ...{ 
  if (s != null) ...{ 
   String centerNo = null; 
   if (s.length() == 11 && s.substring(0, 2).equals("13")) ...{ 
    centerNo = "86" + s; 
   } else if (s.length() == 13 
     && s.substring(0, 4).equals("8613")) ...{ 
    centerNo = s; 
   } else if (s.length() == 14 
     && s.substring(0, 5).equals("+8613")) ...{ 
    centerNo = s.substring(1); 
   } else 
    return; 

   this.smsc= GFString.interChange(centerNo); 
  } 


public void setAddr(String ad) ...{ 
  if (ad != null) ...{ 
   String centerNo = null; 
   if (ad.length() == 11 && ad.substring(0, 2).equals("13")) ...{ 
    centerNo = "86" + ad; 
   } else if (ad.length() == 13 && ad.substring(0, 4).equals("8613")) ...{ 
    centerNo = ad; 
   } else if (ad.length() == 14 && ad.substring(0, 5).equals("+8613")) ...{ 
    centerNo = ad.substring(1); 
   } else if (ad.length() > 0) ...{// 特服号 
    addrFormat = "A1"; 
    addrLen = ad.length(); 
    centerNo = ad; 
   } else 
    return; 

   addr = GFString.interChange(centerNo); 
  } 


/** *//** 
  * 设置编码方式 
  * 
  * @param encoding 
  *            0:表示7-BIT编码 4:表示8-BIT编码 8:表示UCS2编码 
  */ 
public void setMsgCoding(int encoding) ...{ 
  if (encoding == 
   msgCoding = "08"; 
  else if (encoding == 4) 
   msgCoding = "04"; 
  else 
   msgCoding = "00"; 



/** *//** 
  * 短消息内容 
  * 
  * @param content 
  */ 
public void setMsgContent(String content) ...{ 
  if (content != null) ...{ 
   if (content.length() == content.getBytes().length) ...{ 
    msgCoding = "00"; 
    msgLen = content.getBytes().length; 
    msgContent = encode7bit(content); 
     
   } else ...{ 
    msgCoding = "08"; 
    msgContent = GFString.gb2unicode(content); 
    if(msgContent!=null) 
     msgLen=msgContent.length()/2; 
     
   } 
   
   if(msgContent!=null)...{ 
    msgContent=msgContent.toUpperCase(); 
    
   } 
  } 


/** *//** 
  * 
  * @return 经过PDU编码的结果,十六进制字符串形式 
  */ 
public String getCodedResult() ...{ 
  String result = null; 
  final String tp_mti = "11"; 
  final String tp_mr = "00"; 
  final String tp_pid = "00"; 
  final String tp_vp = "00"; 

  if (smsc != null && addr != null && msgContent != null) ...{ 
   result = smscLen + smscFormat + smsc + tp_mti + tp_mr 
     + GFString.byte2hex((byte) addrLen) + addrFormat + addr 
     + tp_pid + msgCoding + tp_vp 
     + GFString.byte2hex((byte) msgLen) + msgContent; 
   result = result.toUpperCase(); 
  } 

  return result; 


public String getAddr() ...{ 
  return addr; 


public String getMsgCoding() ...{ 
  return msgCoding; 


public String getMsgContent() ...{ 
  return msgContent; 


public int getMsgLen() ...{ 
  return msgLen; 


public String getSmsc() ...{ 
  return smsc; 


//TODO:temp 
public static String encode7bit(String src) ...{ 
  String result = null; 
  String hex = null; 
  byte value; 

  if (src != null && src.length() == src.getBytes().length) ...{ 
   result = ""; 
   byte left=0; 
   byte[] b = src.getBytes(); 
   for (int i = 0, j = 0; i < b.length; i++) ...{ 
    j =i & 7; 
    if (j == 0) 
     left = b[i]; 
    else ...{ 
     value =(byte)((b[i] << (8 - j))|left); 
     left=(byte)(b[i]>>j); 
     hex = GFString.byte2hex((byte) value); 
     result += hex; 
     if(i==b.length -1) 
      result+=GFString.byte2hex(left); 
    } 
   } 
   
   result=result.toUpperCase(); 
  } 
  return result; 




/** *//** 
  * 7-BIT编码 把ASCII码值最高位为0的字符串进行压缩转换成8位二进制表示的字符串 
  * 
  * @param src 
  * @return 
  */ 
public static String encode7bit(String src) ...{ 
  String result = null; 
  String hex = null; 
  byte value; 

  if (src != null && src.length() == src.getBytes().length) ...{ 
   result = ""; 
   byte left=0; 
   byte[] b = src.getBytes(); 
   for (int i = 0, j = 0; i < b.length; i++) ...{ 
    j =i & 7; 
    if (j == 0) 
     left = b[i]; 
    else ...{ 
     value =(byte)((b[i] << (8 - j))|left); 
     left=(byte)(b[i]>>j); 
     hex = GFString.byte2hex((byte) value); 
     result += hex; 
     if(i==b.length -1) 
      result+=GFString.byte2hex(left); 
    } 
   } 
   
   result=result.toUpperCase(); 
  } 
  return result; 

    
/** *//** 
  * 对7-BIT编码进行解码 
  * @param src 十六进制的字符串,且为偶数个 
  * @return 源字符串 
  */ 
public static String decode7bit(String src) ...{ 
  String result = null; 
        int[] b; 
        String temp=null; 
        byte srcAscii; 
        byte left=0; 
        
  if (src != null && src.length() %2==0) ...{ 
   result=""; 
           b=new int[src.length() /2]; 
           temp=src+"0"; 
           for(int i=0,j=0,k=0;i<temp.length() -2;i+=2,j++)...{ 
             b[j]=Integer.parseInt(temp.substring(i,i+2),16); 
             
             k=j % 7; 
             srcAscii=(byte)(((b[j]<<k) & 0x7F)|left); 
             result+=(char)srcAscii; 
             left=(byte)(b[j]>>>(7-k)); 
             if(k==6)...{ 
              result+=(char)left; 
              left=0; 
             } 
             if(j==src.length() /2) 
              result+=(char)left; 
           } 
  } 
  return result; 



/** *//** 
  * 把UNICODE编码的字符串转化成汉字编码的字符串 
  * 
  * @param hexString 
  * @return 
  */ 
public static String unicode2gb(String hexString) ...{ 
  StringBuffer sb = new StringBuffer(); 

  if (hexString == null) 
   return null; 

  for (int i = 0; i + 4 <= hexString.length(); i = i + 4) ...{ 
   try ...{ 
    int j = Integer.parseInt(hexString.substring(i, i + 4), 16); 
    sb.append((char) j); 
   } catch (NumberFormatException e) ...{ 
    return hexString; 
   } 
  } 

  return sb.toString(); 


/** *//** 
  * 把汉字转化成UNICODE编码的字符串 
  * 
  * @param gbString 
  * @return 
  */ 
public static String gb2unicode(String gbString) ...{ 
  String result = ""; 
  char[] c; 
  int value; 

  if (gbString == null) 
   return null; 
  // if (gbString.getBytes().length == gbString.length()) 
  // return gbString; 

  String temp = null; 
  c = new char[gbString.length()]; 
  StringBuffer sb = new StringBuffer(gbString); 
  sb.getChars(0, sb.length(), c, 0); 
  for (int i = 0; i < c.length; i++) ...{ 
   value = (int) c[i]; 
   // System.out.println("[" + i + "]:" +value ); 
   // System.out.println("hex:"+Integer.toHexString(value)); 
   temp = Integer.toHexString(value); 
   result += fill(temp, 4); 
  } 

  return result.toUpperCase(); 



4.结束语 

上面的源代码可能并不十分完整,但最重要的部分都有了。做为大家学习考参的例子。 

PDU编码的详细介绍,请参考下面的参考资料 

5.参考资料 

bhw98的专栏 ttp://blog.csdn.net/bhw98/archive/2003/03/27/19666.aspx 

原文地址:http://blog.csdn.net/sinboy/archive/2005/12/10/548549.aspx 
原创粉丝点击