Java实现PDU编码

2023-11-20

代码一:

package com.zte.test;

import java.io.UnsupportedEncodingException;

/**
 * PDU编码实现,7bit,8bit,以及UCS2编码;代码主体是网上来源(Url我忘记了,很遗憾) 自己完善了一点,测试后暂时没错。
 * 
 */
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;
	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 = PduPack.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 = PduPack.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 = PduPack.unicode2gb(temp);
			} else {
				msgContent = PduPack.decode7bit(temp);
			}
		}
	}

	/**
	 * 设置短信中心号码
	 * 
	 * @param s
	 */
	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 = PduPack.interChange(centerNo);
		}
	}

	/**
	 * 设置目的地址
	 * 
	 * @param ad
	 */
	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 = PduPack.interChange(centerNo);
		}
	}

	/**
	 * 设置编码方式
	 * 
	 * @param encoding
	 *            0:表示7-BIT编码 4:表示8-BIT编码 8:表示UCS2编码
	 */
	public void setMsgCoding(int encoding) {
		if (encoding == 8) {
			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 = PduPack.Chinese2unicode(content);
				if (msgContent != null)
					msgLen = msgContent.length() / 2;
			}
			if (msgContent != null) {
				msgContent = msgContent.toUpperCase();
			}
		}
	}

	/**
	 * 
	 * @return 经过PDU编码的结果,十六进制字符串形式
	 */
	public String getCodedResultStr() {
		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
					+ PduPack.byte2hex((byte) addrLen) + addrFormat + addr
					+ tp_pid + msgCoding + tp_vp
					+ PduPack.byte2hex((byte) msgLen) + msgContent;
			result = result.toUpperCase();
		}
		return result;
	}

	/**
	 * 
	 * @return 经过PDU编码的结果,byte数组格式
	 */
	public byte[] getCodedResultByte() {
		return getCodedResultStr().getBytes();
	}

	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;
	}

	/**
	 * 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 = PduPack.byte2hex((byte) value);
					result += hex;
					if (i == b.length - 1)
						result += PduPack.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 s
	 * @return
	 */
	public static String Chinese2unicode(String s) {
		String s1 = new String();
		String s2 = new String();
		byte abyte0[] = null;
		try {
			abyte0 = s.getBytes("Unicode");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		for (int j = 2; j < abyte0.length; j += 2) {
			String s3 = Integer.toHexString(abyte0[j + 1]);
			int i = s3.length();

			if (i < 2) {
				s1 = s1 + "0" + s3;
			} else {
				s1 = s1 + s3.substring(i - 2);
			}

			s3 = Integer.toHexString(abyte0[j]);
			i = s3.length();

			if (i < 2) {
				s1 = s1 + "0" + s3;
			} else {
				s1 = s1 + s3.substring(i - 2);
			}
		}
		return s1;
	}

	/**
	 * byte数据转化成为十六进制ASCII字符
	 * 
	 * @param ib
	 * @return
	 */
	public static String byte2hex(byte ib) {
		char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
				'B', 'C', 'D', 'E', 'F' };
		char[] ob = new char[2];
		ob[0] = Digit[(ib >>> 4) & 0X0F];
		ob[1] = Digit[ib & 0X0F];

		String s = new String(ob);

		return s;
	}

	/**
	 * 把相临的两个字符对换,字符串长度为奇数时最后加“F”
	 * 
	 * @param src
	 * @return
	 */
	public static String interChange(String src) {
		String result = null;
		if (src != null) {
			if (src.length() % 2 != 0) {
				src += "F";
			}

			src += "0";
			result = "";

			for (int i = 0; i < src.length() - 2; i += 2) {
				result += src.substring(i + 1, i + 2);
				result += src.substring(i, i + 1);
			}
		}
		return result;
	}
}


代码二:

package com.zte.test;

//根据需要在不断完善当中 更新时间:2010-10-20 14:12
//已实现 7bit,16bit编码,7bit,16bit解码
//采用了http://commons.apache.org/codec/ 提供的开发包解析 hex string to byte[]
//PDU串的用户信息长度(TP-UDL),在各种编码方式下意义有所不同。
//7-bit编码时,指原始短消息的字符个数,而不是编码后的字节数。
//8-bit编码时,就是字节数。UCS2编码时,也是字节数,等于原始短消息的字符数的两倍。
import java.io.UnsupportedEncodingException;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

public class PduCodec {
	// 7bit-160,8bit-140,16bit-70
	private String SCA = "00"; 
	// Service Center Adress [1-12] 服务中心的电话号码
	private String SMSC = "+019000001";
	// private byte PduType;
	// Protocol Data Unit Type [1] 协议数据单元类型
	private String PduTypeHex = "31";
	// private String MR = "00"; 
	// Message Reference [1] 所有成功的 SMS-SUBMIT
	// 参考数目(0..255)
	private String OA; 
	// Originator Adress [2-12] 发送方 SME 的地址
	// private String DA; 
	// Destination Adress [2-12] 接收方 SME 的地址
	// private String PID = "00"; 
	// Protocol Identifier [1] 参数显示 SMSC以何种方式处理SM
	// (比如FAX,、Voice 等)
	private byte DCS; 
	// Data Coding Scheme [1] 参数表示用户数据(UD)采用什么编码方案
	private String DcsHex = "00"; 
	// Data Coding Scheme [1] 参数表示用户数据(UD)采用什么编码方案
	private String SCTS; 
	// Service Center Time Stamp [7] 参数表示
	// SMSC接收到消息时的时间戳
	// private String VP; 
	// Validity Period [0,1,7] 参数表示消息在 SMSC中不再有效的时长
	// private String UDL; 
	// User Data Length [1] 用户数据段长度
	// private String UD; 
	// User Data [0-140] SM数据
	private boolean GSM = false; // GSM 压缩
	private byte Alphabet = 0; // 字母表

	// private byte ValidBits[] = { 0, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };

	// 00 – 默认的字母表,每个字符占用 7 比特位,此时最大可以传送 160 字符
	// 01 – 8bit,此时最大只能传送 140 个字符
	// 10 – USC2(16bit), 传送双字节字符集
	public static void main(String[] args) {
		PduCodec pc = new PduCodec();
		// String src =
		// "0891683108802505F22405800180F60008013022710413236A60A876847F514E0A5BA2670D4E1A52A153D7740662168BE6535567E58BE276844E8C6B21927467435BC678014E3AFF1A003500380035003600390039FF0C003200305206949F518553EF4EE54F7F75288BE55BC67801529E74064E1A52A1621667E58BE28BE653553002";
		// String src =
		// "07911326040000F0040B911346610089F60000208062917314080CC8F71D14969741F977FD07";
		// System.out.println(pc.Decode(src));
		System.out.println(pc.Encode("0192292309", "中文短信息编码"));
	}

	private String decodeSMSC(String data) {// 读取短信中心号码
		String SCA_Len = data.substring(0, 2);
		System.out.println("sca_len=" + SCA_Len);
		String SCA_Type = data.substring(2, 4);
		System.out.println("sca_type=" + SCA_Type);
		int sca_len = Integer.parseInt(SCA_Len, 16);
		int sca_eidx = (sca_len + 1) * 2;
		String sca_str = data.substring(0, sca_eidx);
		StringBuilder sb = new StringBuilder();
		if (SCA_Type.equals("91")) {
			sb.append("+");
			sca_len--;
		}
		for (int i = 0; i < sca_len * 2; i += 2) {
			sb.append(sca_str.charAt(i + 5));
			char sca_tmp = sca_str.charAt(i + 4);
			if ('F' != sca_tmp) {
				sb.append(sca_tmp);
			}
		}
		System.out.println("SMSC#" + sb.toString());
		System.out.println("src:=" + sca_str);
		int data_len = data.length();
		return data.substring(sca_eidx, data_len);
	}

	private String decodePduType(String data) {
		int PduType_eidx = 2;
		PduTypeHex = data.substring(0, PduType_eidx);
		System.out.println("PduType:" + PduTypeHex);
		System.out.println("src:=" + PduTypeHex);
		int data_len = data.length();
		return data.substring(PduType_eidx, data_len);
	}

	private String decodeSME(String data, String addr) {
		String SME_Len = data.substring(0, 2);
		System.out.println("sme_len=" + SME_Len);
		String SME_Type = data.substring(2, 4);
		System.out.println("sme_type=" + SME_Type);

		int sme_len = Integer.parseInt(SME_Len, 16);
		if (0 != sme_len % 2) {
			sme_len++;
		}
		int sme_eidx = sme_len + 4;
		StringBuilder sb = new StringBuilder();
		if (SME_Type.equals("91")) {
			sb.append("+");
		}
		for (int i = 0; i < sme_len; i += 2) {
			sb.append(data.charAt(i + 5));
			char tmp = data.charAt(i + 4);
			if ('F' != tmp) {
				sb.append(tmp);
			}
		}
		OA = sb.toString();
		System.out.println(addr + OA);

		String SME_str = data.substring(0, sme_eidx);
		System.out.println("src:=" + SME_str);

		int data_len = data.length();
		return data.substring(sme_eidx, data_len);

	}

	private String decodePID(String data) {
		int pid_eidx = 2;
		String PID_Str = data.substring(0, pid_eidx);
		System.out.println("TP_PID:" + PID_Str);
		System.out.println("src:=" + PID_Str);
		int data_len = data.length();
		return data.substring(pid_eidx, data_len);
	}

	private String decodeDCS(String data) {
		int dcs_eidx = 2;
		DcsHex = data.substring(0, dcs_eidx);
		DCS = (byte) Integer.parseInt(DcsHex, 16);
		System.out.println("TP_DCS:" + DcsHex);
		GSM = (DCS & 0x20) == 0x20;
		if (GSM) {
			System.out.println("文本用GSM标准压缩算法压缩");
		} else {
			System.out.println("文本未压缩");
		}
		if (((DCS & 0x08) != 0x08) && ((DCS & 0x04) != 0x04)) {
			System.out.println("Alphabet = 7bit");
			Alphabet = 0;
		} else if (((DCS & 0x08) != 0x08) && ((DCS & 0x04) == 0x04)) {
			System.out.println("Alphabet = 8bit");
			Alphabet = 1;
		} else if (((DCS & 0x08) == 0x08) && ((DCS & 0x04) != 0x04)) {
			System.out.println("Alphabet = 16bit");
			Alphabet = 2;
		} else {
			System.out.println("Alphabet = unknow");
		}

		if (((DCS & 0x02) != 0x02) && ((DCS & 0x01) != 0x01)) {
			System.out.println("Class 0 Immediate display");
		} else if (((DCS & 0x02) != 0x02) && ((DCS & 0x01) == 0x01)) {
			System.out.println("Class 1 ME specific");
		} else if (((DCS & 0x02) == 0x02) && ((DCS & 0x01) != 0x01)) {
			System.out.println("Class 2 SIM specific");
		} else if (((DCS & 0x02) == 0x02) && ((DCS & 0x01) == 0x01)) {
			System.out.println("Class 3 TE specific");
		} else {
			System.out.println("Class unknow");
		}

		System.out.println("src:=" + DcsHex);
		int data_len = data.length();
		return data.substring(dcs_eidx, data_len);
	}

	private String decodeSCTS(String data) {
		int vpf_eidx = 0;
		int vp_eidx = 14;
		String VP_Str = data.substring(vpf_eidx, vp_eidx);
		SCTS = String.format("20%c%c-%c%c-%c%c %c%c:%c%c:%c%c",
				VP_Str.charAt(1), VP_Str.charAt(0), VP_Str.charAt(3),
				VP_Str.charAt(2), VP_Str.charAt(5), VP_Str.charAt(4),
				VP_Str.charAt(7), VP_Str.charAt(6), VP_Str.charAt(9),
				VP_Str.charAt(8), VP_Str.charAt(11), VP_Str.charAt(10));
		System.out.println("TimeStamp:" + SCTS);
		String tmp2 = String.format("%c%c", VP_Str.charAt(13),
				VP_Str.charAt(12));
		System.out.println("Time Zone:" + tmp2);

		System.out.println("src:=" + VP_Str);
		int data_len = data.length();
		return data.substring(vp_eidx, data_len);
	}

	private String decodeUD(String data) {
		int udl_eidx = 2;
		String UDL_Str = data.substring(0, udl_eidx);
		int char_len = Integer.parseInt(UDL_Str, 16);
		int byte_len = char_len;
		System.out.println("udl_len=" + char_len);
		String UD_HexStr = data.substring(udl_eidx, udl_eidx + char_len * 2);
		String UD_Str = null;
		if (0 == Alphabet) {
			StringBuilder sb = new StringBuilder();
			byte[] ud_array1 = new byte[char_len];
			try {
				ud_array1 = Hex.decodeHex(UD_HexStr.toCharArray());
				int j = char_len * 7;
				byte_len = j / 8;
				if (0 != j % 8) {
					byte_len++;
				}
				int a0 = 0, a1, a2;
				for (int i = 0; i < byte_len; i++) {
					j = i % 7;
					a1 = ud_array1[i] & 0xFF;
					a2 = ((a1 << j) & 0x7F) | a0;
					sb.append((char) a2);
					if (6 != j) {
						a0 = ((a1 >> (7 - j)) & 0x7F);
					} else {
						a2 = ((a1 >> 1) & 0x7F);
						sb.append((char) a2);
						a0 = 0;
					}
				}
			} catch (DecoderException e) {
				e.printStackTrace();
			}
			UD_Str = sb.toString();
		} else if (1 == Alphabet) {
			UD_Str = "还未处理的8位解码";
		} else if (2 == Alphabet) {
			byte[] ud_array = new byte[char_len];
			try {
				ud_array = Hex.decodeHex(UD_HexStr.toCharArray());
				UD_Str = new String(ud_array, "UTF-16");
			} catch (DecoderException e) {
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		System.out.println("ud_str:=" + UD_Str);
		int data_len = data.length();
		System.out.println("src:=" + data.substring(udl_eidx, data_len));
		String str = "time:" + SCTS + " from:" + OA + " content:" + UD_Str;
		return str;
	}

	public String encodeSMSC(String sCA) {// 设置短信中心号码
	// Len[1] + Type[0-1] + Addr[0-10]
	// Type 含符号"+"国际0x91, 国内0x81
	// Len = Type + Addr 字节和
		if ((null != sCA) && (0 < sCA.length())) {
			String SCA_Type;
			String SCA_Addr0;
			StringBuilder SCA_Addr1 = new StringBuilder();
			if (sCA.startsWith("+")) {
				SCA_Type = "91";
				SCA_Addr0 = sCA.substring(1);
			} else {
				SCA_Type = "81";
				SCA_Addr0 = sCA;
			}
			if (0 != SCA_Addr0.length() % 2) {
				SCA_Addr0 += "F";
			}
			String SCA_Len = String.format("%02X", 1 + SCA_Addr0.length() / 2);
			for (int i = 0; i < SCA_Addr0.length(); i += 2) {
				SCA_Addr1.append(SCA_Addr0.charAt(i + 1));
				SCA_Addr1.append(SCA_Addr0.charAt(i));
			}
			SCA = SCA_Len + SCA_Type + SCA_Addr1.toString();
			return SCA;
		} else {
			System.out.println("短信中心设置错误!");
			return null;
		}
	}

	public String encodePduType(String Pdu) {
		return Pdu;
	}

	public String encodeMR(String mR) {
		return mR;
	}

	public String encodePID(String pID) {
		return pID;
	}

	private String encodeDA(String sME) {
		// Len[1] + Type[0-1] + Addr[0-10]
		// Len:地址长度。指 8613851724908 的字符个数长度。这与 SCA中的定义不一样!
		// Type 含符号"+"国际0x91, 国内0x81
		// Len = Type + Addr 字节和
		String SME_Len = "00";
		String SME_Type = "00";
		String SME_Addr0;
		StringBuilder SME_Addr1 = new StringBuilder();
		if ((null != sME) && (0 < sME.length())) {
			if (sME.startsWith("+")) {
				SME_Type = "91";
				SME_Addr0 = sME.substring(1);
			} else if (sME.startsWith("106")) {// 小灵通
				SME_Type = "A1";
				SME_Addr0 = sME;
			} else {
				SME_Type = "81";
				SME_Addr0 = sME;
			}
			SME_Len = String.format("%02X", SME_Addr0.length());
			if (0 != SME_Addr0.length() % 2) {
				SME_Addr0 += "F";
			}
			for (int i = 0; i < SME_Addr0.length(); i += 2) {
				SME_Addr1.append(SME_Addr0.charAt(i + 1));
				SME_Addr1.append(SME_Addr0.charAt(i));
			}
		} else {
			System.out.println("设置SME地址错误!请输入正确的SME地址");
		}
		return SME_Len + SME_Type + SME_Addr1.toString();
	}

	public String encodeDCS(String dCS) {
		return dCS;
	}

	public String encodeVP(String vP) {
		return vP;
	}

	public String encodeUD(String uD) {
		int sLen = uD.length();
		String tmp1 = String.format("%02X", sLen);
		String tmp2 = null;
		byte[] src = uD.getBytes();
		if (uD.length() == uD.getBytes().length) {
			int j = sLen * 7;
			int dLen = j / 8;
			if (0 != j % 8) {
				dLen++;
			}
			byte[] dst = new byte[dLen];
			int sIdx = 0, dIdx = 0, BitsLeft = 0, BitsFill;
			while (dIdx < dLen) {
				if (0 < BitsLeft) {
					BitsFill = (src[sIdx] << (8 - BitsLeft)) & 0xFF;// 要前移的 bits
					dst[dIdx - 1] = (byte) (dst[dIdx - 1] | BitsFill);// 前移数据到前一个字节
					dst[dIdx] = (byte) (src[sIdx] >>> BitsLeft);// 前移数据后的字节
					if (6 == BitsLeft) {
						dst[dIdx] |= (byte) (src[++sIdx] << 1);
						BitsLeft = 0;
					} else {
						BitsLeft++;
					}
					dIdx++;
					sIdx++;
				} else {
					dst[dIdx++] = (byte) (src[sIdx++] & 0x7F);
					BitsLeft = 1;
				}
			}
			dIdx = 0;
			while (dIdx < dLen) {
				tmp2 = String.format("%02X", dst[dIdx++]);// 已经充满的字节
				tmp1 += tmp2;
			}
		} else {
			int dLen = sLen * 2;
			byte[] dst = new byte[dLen];
			try {
				tmp1 = String.format("%02X", dLen);
				byte[] tmp = uD.getBytes("UTF-16");
				System.arraycopy(tmp, 2, dst, 0, dLen);
				tmp1 += new String(Hex.encodeHex(dst, false));
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return tmp1;
	}

	public String Decode(String data) {
		System.out.println(data);
		String tmp = decodeSMSC(data);
		tmp = decodePduType(tmp);
		tmp = decodeSME(tmp, "Sender:");
		tmp = decodePID(tmp);
		tmp = decodeDCS(tmp);
		tmp = decodeSCTS(tmp);
		tmp = decodeUD(tmp);
		return tmp;
	}

	public String Encode(String Tel, String Data) {
		String tmp = encodeSMSC(SMSC);
		tmp += encodePduType("11");
		tmp += encodeMR("00");
		tmp += encodeDA(Tel);
		tmp += encodePID("00");
		if (Data.length() == Data.getBytes().length) {
			tmp += encodeDCS("00");// 00:7bit编码
		} else {
			tmp += encodeDCS("08");// 00:16bit编码
		}
		tmp += encodeVP("AA");// AA 有效期四天
		tmp += encodeUD(Data);
		return tmp;
	}
}
// AT+CMGF=0
// OK
// AT+CMGL=4
// +CMGL: 1,1,,64
// 0891683110102105F06405A10110F000080101905103342330050003010202002E00310030003000310030002E0063006F006DFF0C5145503C0039002E0038003562984F1860E0FF01
// +CMGL: 2,1,,152
// 0891683110102105F06405A10110F000080101905103842388050003010201622A6B62523000320030003100305E740031003067080030003965E5FF0C60A876845E1062374F59989D4E3A00320030002E003700305143FF0C53D19001201C0043005A00235145503C53615BC67801201D81F300310030003000310030537353EF5145503CFF0C6216767B5F558054901A7F514E0A84254E1A5385007700770077


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现PDU编码 的相关文章

随机推荐

  • docker入门---最全笔记

    前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识 有兴趣的小伙伴可以关注一下 也许一个人独行 可以走的很快 但是一群人结伴而行 才能走的更远 让我们在成长的道路上互相学习 让我们共同进步 欢迎关注 目录 前言 一 D
  • FFMPEG进阶系列02-ffmpeg命令详解3

    文章目录 ffmpeg 的封装转换 ffmpeg的编转码 ffmpeg 的基本编转码原理 过滤器链 filter chain 码率 帧率和文件大小 帧率 帧率和文件大小 调整视频分辨率 调整视频分辨率 scale filter调整分辨率 裁
  • Go Web编程实战(10)----模板引擎库text/template包的使用

    目录 前言 模板引擎 定义模板文件 解析模板文件 渲染模板 实战使用模板 创建 tmpl文件 创建文件用于解析与渲染模板 前言 在Go语言中 模板引擎库text template包主要用于处理任意格式的文本内容 同时还提供了html tem
  • IP网址可访问,域名网址无法访问

    可以通过修改DNS排查问题 一 修改DNS的好处 适当提高上网速度 更换DNS可以访问某些因为域名解析存在问题而不能访问的网站 可以屏蔽运营商的广告 还可以帮助您避免被钓鱼的危险 二 修改DNS带来的副作用 无法访问页面或者访问的页面不是你
  • Ubuntu 20.04 配置深度学习开发环境

    目录 写在前面 Dependency 1 安装Anaconda 1 1 下载安装包 1 2 进入安装文件夹 执行安装脚本 1 3 环境变量的配置与更新 1 4 测试安装 1 5 创建虚拟环境 2 安装英伟达驱动 法一 命令行安装 法二 GU
  • 1264 - Out of range value for column 'id' at row 1

    1 我用的是mysql 在数据插入是报错 原因是我插入的值 超过了数据库中类型和长度设置 1 1 我的插入语句 注意 id 的值 INSERT INTO test id sex name username password classes
  • Vue —— 锚点导航

    一个页面中分为多块 例如 目录一 目录二 目录三等 这就需要加上一个锚点导航的需求 提高用户的操作性 原生的写法 div class wrapper ul li a href catalogue1 目录一 a li li a href ca
  • SpringCloud概述

    SpringCloud概述 1 SpringCloud是什么 2 SpringCloud和SpringBoot关系 3 Dubbo和SpringCloud技术选型 4 SpringCloud作用 1 SpringCloud是什么 现代化的J
  • How to compile rocksdb with lz4 support

    On CentOS 6 x or 7 x you can do the following to easily install lz4 using the package manager As root sudo su is your fr
  • 137-----JS基础-----类的操作

    一 代码 不算难 如果后续操作到类的话 可以直接使用下面封装好的接口到自己的tool中
  • 线性回归建模及模型诊断

    目录 一 建模背景及目的及数据源说明 二 描述性分析 2 1 连续自变量与连续因变量的相关性分析 2 2 二分类变量与连续变量的相关性分析 2 3 多分类变量与连续变量的相关性分析 三 模型建立与诊断 3 1 一元线形回归及模型解读 3 2
  • 编码技巧——校验器(职责链+抽象模版)

    日常开发中可能遇到这样的业务场景 请求从入口进来 需要经过层层的校验 通过校验后才会执行业务操作 写操作 RPC 异步消息 这里前置的多层校验流程中 从类型上看 部分是基本参数校验 部分是包含业务逻辑的校验 并且部分校验是可以并行 部分是有
  • 矩阵的分解——LU分解

    LU分解 LU分解是矩阵分解的一种 将一个矩阵分解为一个下三角矩阵和一个上三角矩阵的乘积 有时需要再乘上一个置换矩阵 LU分解可以被视为高斯消元法的矩阵形式 在数值计算上 LU分解经常被用来解线性方程组 且在求逆矩阵和计算行列式中都是一个关
  • OSQP二次规划求解库使用说明

    OSQP二次规划求解库使用说明 贺志国 2023 5 10 1 凸二次规划的一般表达式 m i n 1 2 x
  • 微信API接口访问慢

    场景 项目需要调用微信API接口获得微信用户信息 本地开发和公司测试环境中测试十分顺利 但是在部署到现场环境中 接口调用经常会很慢 需要几分钟的时间才能返回值 现场环境的服务器因为客户原因 只能指定申请特定个别IP访问 无法开放微信接口域名
  • MySQL中常用工具

    作者 小刘在C站 个人主页 小刘主页 努力不一定有回报 但一定会有收获加油 一起努力 共赴美好人生 学习两年总结出的运维经验 以及思科模拟器全套网络实验教程 专栏 云计算技术 小刘私信可以随便问 只要会绝不吝啬 感谢CSDN让你我相遇 目录
  • vue3使用事件委托实现选项卡的切换

    选项卡是js写的 不是组件 ul li item li ul
  • 虚拟机不能上网,ifconfig显示只有lo

    1 开启虚拟机后无法上网 ifconfig查询发现只有本地环回网口 2 使用 ifconfig a 命令查三腊鉴看是否存在网卡 3 查询结果显示系统中存在ens33和ens37网卡 解决方法就是要启动ens33网卡 并配置其IP地址等信息
  • JavaScript面向对象:类的几种继承方式

    面向对象 类的几种继承方式 类与实例 类的声明 生成实例 类与继承 如何实现继承 继承的几种方式 前端小白记录学习笔记 不做他用 类与实例 类的声明 用构造函数模拟类 传统写法 function Person1 name this name
  • Java实现PDU编码

    代码一 package com zte test import java io UnsupportedEncodingException PDU编码实现 7bit 8bit 以及UCS2编码 代码主体是网上来源 Url我忘记了 很遗憾 自己