Decoding PDU SMS with java

There are three questions: 1. What is PDU short message; 2. Why use pdu; 3. How to decode with java

1. What is PDU short message?

One way of short message, supported by all mobile phones, can use any character set, which is also the default encoding method of mobile phones;
PDU is equivalent to a data package, which consists of information that constitutes a message (SMS). As a data unit, it must contain source/destination address, protection (valid) time, data format, protocol type and text, which can reach 140 bytes in length and are all represented in hexadecimal system. The structure of PDU varies according to whether short message is initiated by mobile terminal or for mobile terminal purposes. Each message can send 140 bytes. Since the longest data string in the system does not exceed 140 bytes, the data can be sent by one message.
There are 7 bit-160, 8 bit-140, 16 bit-70 in Chinese, and 16 bit-70 in Chinese.

Example
Send: SMSC number is + 8613800250500, the other party number is 13851872468, the message content is "Hello!".

PDU strings from mobile phones can be 08 91 68 31 08 20 05 05 F0 11 00 D 91 68 31 58 81 27 64 F8 00 06 C8 32 9 B FD 0E 01

Contrast with the norms and analyze them concretely:___________
08. Length of SMSC Address Information. A total of 8 8 bytes (including 91)
91. SMSC Address Format (TON/NPI). Use International Format Number (with'+'in front)
68 31 08 20 05 05 F0 SMSC address 8613800250500, make up an even number of'F'
11. Basic parameters (TP-MTI/VFP) are sent, and TP-VP is in relative format.
00. Message Baseline Value (TP-MR) 0
0D. Number of target address digits. Total 13 decimal digits (excluding 91 and'F')
91. Target Address Format (TON/NPI). Use International Format Number (with'+'in front)
68 31 58 81 27 64 F8 Target Address (TP-DA) 8613851872468, complement'F'to make even number, BCD encoding, low-high bit mode
 
00) Protocol Identification (TP-PID) is a common GSM type, point-to-point mode.
00) User Information Coding (TP-DCS) 7-bit Coding
 
00) Term of validity (TP-VP) 5 minutes
 
06) User Information Length (TP-UDL). Actual Length 6 Bytes

C8 329B FD 0E 01 User Information (TP-UD) "Hello!"

 

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

Analysis
Segmentation
Meaning
Explanation
 
08 
The length of SMSC address information
A total of 8 octets (including 91)
 
91 
SMSC Address Format (TON/NPI)
In international format (with'+'before), 81 indicates no+
 
683108100005F0 
SMSC address
8613800100500, complement'F'to compose even number of bcd codes
31 
Basic parameters (TP-MTI/VFP)
Send, TP-VP in relative format. sign
 
00 
Message Baseline Value (TP-MR)
 0
 
0D 
Number of target addresses
A total of 13 decimal digits (excluding 91 and `F')
 
81 
Target Address Format (TON/NPI)
In international format (with'+'in front), 81 means no'+'.
 
3129503323F1 
Target address (TP-DA)
8613851872468, complement'F'to make even number, BCD coding, low-high bit mode
 
00 
Protocol Identification (TP-PID)
General GSM type, point-to-point mode
 
08 
User Information Coding (TP-DCS)
16-bit coding, UCS2 coding
 
A8 
Validity period (TP-VP)
2 days
 
0C
User Information Length (TP-UDL)
12 bytes in length
 
4F6060F3776189C94E865427 
User Information (TP-UD)
"You go to bed!"



2. Why use pdu?
Supported by all mobile phones
Universal hexadecimal system


3. How to decode with java?
For the time being, only 7-bit and 16-bit (UCS2, UCS2 encoding for sending Unicode characters) decoding codes are shown.

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 Decode
	* @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];
	//Get my data
	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);
	}
	//Take the next data information away first
	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++) {
						//Because it's hexadecimal, it only takes up to four bits at most. Converting to bytes requires two hexadecimal characters, with high bits first.
						//Converting hex to byte "&" operation to prevent automatic expansion of negative numbers
						// Converting hex to byte actually takes up only four bits, and then shifts the top four to the right.
						// Then "|" operates four bits lower to get two hexadecimal digits converted into a 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 ("Hexadecimal plaintext string converted to hexadecimal byte array:" +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("Exceptional characters:"+src.substring(i, i + 2));
			}
		}
		String reValue="";
		try {
			reValue = new String(bytes, "UTF-16BE");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return reValue;

	}




Other reference links:
http://www.cnblogs.com/heiyue/p/7008499.html
http://blog.csdn.net/yangfeiyang/article/details/5526649

Keywords: Mobile encoding Java

Added by langer on Sat, 01 Jun 2019 23:06:37 +0300