| 
					
				 | 
			
			
				@@ -0,0 +1,113 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package com.nokia.sms.blacklist; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.nio.ByteBuffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.security.MessageDigest; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.security.NoSuchAlgorithmException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.text.DateFormat; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.text.SimpleDateFormat; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Arrays; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import java.util.Date; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import org.snmp4j.smi.OctetString; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import lombok.extern.slf4j.Slf4j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 构建由客户端发送给服务器的各类消息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 协议参考 河北联通垃圾短信一键解黑接口规范.docx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 这里需要注意一下,规范中是c-octet string 需要在末尾加上 0x00 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Slf4j 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class RequestMessageUtil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 协议中SMIT_BIND 绑定请求消息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     *  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * @throws NoSuchAlgorithmException 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static byte[] getSmitBindMessage(String username, String password) throws NoSuchAlgorithmException { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // header 4+4+4 body 16+20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int messageLength = 48; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] message = new byte[messageLength]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Arrays.fill(message, (byte) 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 填充header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 前4个(0-3)字节是 Unsigned Integer 消息长度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[3] = (byte) messageLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 4-7字节是消息类型 Command ID SMIT_BIND 绑定请求为 0x00000001 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[7] = (byte) 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 8-11字节是消息序列号 从0到0XFFFFFFFF之间 请求的应该从0开始 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 填充body 16+20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // system_id 登录用户id username 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] byteArraySystemId = new OctetString(username).toByteArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 把username的字节复制到message 从12开始到27结束 27位应为0x00 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 用户名转化成octet字符串后可能小于16位 因此开始位数应该是 28 - byteArraySystemId.length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.arraycopy(byteArraySystemId, 0, message, 27 - byteArraySystemId.length, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                byteArraySystemId.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // authcode 28位开始 共 20位 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] octetAuthcode = new OctetString(password + dateFormat.format(new Date())).toByteArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        MessageDigest digest = MessageDigest.getInstance("SHA-1"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // sha1后正好20位 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        octetAuthcode = digest.digest(octetAuthcode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.arraycopy(octetAuthcode, 0, message, 28, 20); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log.debug("已完成SMIT_BIND消息组装: {}", Arrays.toString(message)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return message; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 协议中SMIT_ACTIVE_TEST 链路检测请求 消息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static byte[] getSmitAciveTestMessage(long messageCount) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // header 4+4+4 body为空 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int messageLength = 12; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] message = new byte[messageLength]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Arrays.fill(message, (byte) 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 填充header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 前4个(0-3)字节是 Unsigned Integer 消息长度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[3] = (byte) messageLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 4-7字节是消息类型 SMIT_ACTIVE_TEST 0x0000000f 链路检测 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[7] = (byte) 15; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 8-11字节是消息序列号 从0到0XFFFFFFFF之间 请求的应该从0开始 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ByteBuffer byteBuffer = ByteBuffer.allocate(8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byteBuffer.putLong(0, messageCount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // java中没有unsigned integer 用long表示以后需要截取后4位byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.arraycopy(byteBuffer.array(), 4, message, 8, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return message; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * 协议中的 SMIT_DELBLK 0x00000003 解除黑名单请求 消息 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public static byte[] getSmitDelblkMessage(long messageCount, String phoneNumber, boolean isMo) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // header 4+4+4 body为21+1+1+1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int messageLength = 36; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] message = new byte[messageLength]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Arrays.fill(message, (byte) 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 填充header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 前4个(0-3)字节是 Unsigned Integer 消息长度 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[3] = (byte) messageLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 4-7字节是消息类型 SMIT_DELBLK 0x00000003 解除黑名单请求 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[7] = (byte) 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 8-11字节是消息序列号 从0到0XFFFFFFFF之间 请求的应该从0开始 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ByteBuffer byteBuffer = ByteBuffer.allocate(8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byteBuffer.putLong(0, messageCount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // java中没有unsigned integer 用long表示以后需要截取后4位byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.arraycopy(byteBuffer.array(), 4, message, 8, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 填充body 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 11-32字节 blk_num 21字节 点对点和网间用户黑名单号码带86,端口用户黑名单号码不带86 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        byte[] blk_num = new OctetString(phoneNumber).toByteArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        System.arraycopy(blk_num, 0, message, 33 - blk_num.length, blk_num.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 33字节 blk_type 1 黑名单号码 2 黑名单 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[33] = (byte) 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 34字节 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[34] = (byte) (isMo ? 1 : 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 35字节 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message[35] = (byte) 14; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return message; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |