最近在做毕设,用到了这个,搜了下网友有实现,我稍微修改了下把android库去掉了,纯java库


import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.util.Calendar;/** * Created by ashqal on 15-1-16. */public class PduEncoder{    public static Object[] createFakeSms( String sender, String body) {        byte[] pdu = null;        byte[] scBytes = networkPortionToCalledPartyBCD("0000000000"); //短信中心号码,调用networkPortionToCalledPartyBCD转换为BCD二进制码格式.        byte[] senderBytes = networkPortionToCalledPartyBCD(sender);   //伪造的发信号码.        int lsmcs = scBytes.length;  //短信中心的号码长度。        try {            ByteArrayOutputStream bo = new ByteArrayOutputStream();            bo.write(lsmcs);            bo.write(scBytes); //以上两项是SCA            bo.write(0x04); //PDU TYPE            bo.write((byte) sender.length());   //所伪造发件号码的长度。            bo.write(senderBytes); //以上两项是OA            bo.write(0x00); //PID            try {                byte[] bodybytes = EncodeUCS2(body,null);  //用EncodeUCS2函数将短信内容编码为UCS2,短信的长度在函数中已经计算并加入body的头部.                bo.write(0x08); // 0x08代表UCS-2编码格式                //Log.e("编码结果",getBCDString());                bo.write(str2Bcd(getBCDString()));   //以BCD格式写入当前时间                bo.write(bodybytes); //写入短信内容            } catch (Exception e) {            }            pdu = bo.toByteArray();  //最后把结果转换成byte        } catch (IOException e) {        }        return new Object[] { pdu };    }    /**     * 取当前日期并转换为BCD格式     * 输出String共14位,每两位为一时间单位,每个时间单位均为位数倒置,最后两位是offset:     * 年+月+日+时+分+秒+offset     * 只适用于offset取值23的情况     * @return     */    private static String getBCDString(){        String BCDDate="";        String YEAR,MONTH,DAY,HOUR,MINUTE,SECOND;        Calendar now = Calendar.getInstance();        YEAR=String.valueOf(now.get(Calendar.YEAR));        MONTH=String.valueOf(now.get(Calendar.MONTH)+1);  //Calendar的月份是从0开始的,即0代表1月份,故此处要加1.        DAY=String.valueOf(now.get(Calendar.DAY_OF_MONTH));        HOUR=String.valueOf(now.get(Calendar.HOUR_OF_DAY));        MINUTE=String.valueOf(now.get(Calendar.MINUTE));        SECOND=String.valueOf(now.get(Calendar.SECOND));        BCDDate=FmtBCDDate(YEAR.substring(2))+FmtBCDDate(MONTH)+FmtBCDDate(DAY)+                FmtBCDDate(HOUR)+FmtBCDDate(MINUTE)+FmtBCDDate(SECOND)+"23"; //offset为23        return BCDDate;    }    /**     * 日期格式化函数,一位数后面加零变两位数,两位数则颠倒位数     * @param s     * @return     */    private static String FmtBCDDate(String s){        if(ReverseInt(Integer.parseInt(s)).equals("0"))        {            return "00";        }        else        {            if(ReverseInt(Integer.parseInt(s)).length()==1)                return ReverseInt(Integer.parseInt(s))+"0";            else                return ReverseInt(Integer.parseInt(s));        }    }    /**     * 整数位数颠倒函数 ,输出String.     * @param i     * @return     */    private static String ReverseInt(int i){        StringBuffer bs = new StringBuffer(String.valueOf(i));        return bs.reverse().toString();    }    /**     * String转BCD编码函数,来自网络.     * @param asc     * @return     */    private static byte[] str2Bcd(String asc) {        int len = asc.length();        int mod = len % 2;        if (mod != 0) {            asc = "0" + asc;            len = asc.length();        }        byte abt[] = new byte[len];        if (len >= 2) {            len = len / 2;        }        byte bbt[] = new byte[len];        abt = asc.getBytes();        int j, k;        for (int p = 0; p < asc.length()/2; p++) {            if ( (abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {                j = abt[2 * p] - '0';            } else if ( (abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {                j = abt[2 * p] - 'a' + 0x0a;            } else {                j = abt[2 * p] - 'A' + 0x0a;            }            if ( (abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {                k = abt[2 * p + 1] - '0';            } else if ( (abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {                k = abt[2 * p + 1] - 'a' + 0x0a;            }else {                k = abt[2 * p + 1] - 'A' + 0x0a;            }            int a = (j << 4) + k;            byte b = (byte) a;            bbt[p] = b;        }        return bbt;    }    /**     * 以UCS-2格式编码String,用于发送汉字,使用此格式编码最多可发送70个字。     * @param message     * @param header     * @return     * @throws java.io.UnsupportedEncodingException     */    private static byte[] EncodeUCS2(String message, byte[] header)            throws UnsupportedEncodingException {        byte[] userData, textPart;        textPart = message.getBytes("UTF-16BE");        if (header != null) {            userData = new byte[header.length + textPart.length + 1];            userData[0] = (byte)header.length;            System.arraycopy(header, 0, userData, 1, header.length);            System.arraycopy(textPart, 0, userData, header.length + 1, textPart.length);        }        else {            userData = textPart;        }        byte[] ret = new byte[userData.length+1];        ret[0] = (byte) (userData.length & 0xff );        System.arraycopy(userData, 0, ret, 1, userData.length);        return ret;    }    /**     * Note: calls extractNetworkPortion(), so do not use for     * SIM EF[ADN] style records     *     * Returns null if network portion is empty.     */    private static byte[]    networkPortionToCalledPartyBCD(String s) {        String networkPortion = extractNetworkPortion(s);        return numberToCalledPartyBCDHelper(networkPortion, false);    }    /** Extracts the network address portion and canonicalizes     *  (filters out separators.)     *  Network address portion is everything up to DTMF control digit     *  separators (pause or wait), but without non-dialable characters.     *     *  Please note that the GSM wild character is allowed in the result.     *  This must be resolved before dialing.     *     *  Returns null if phoneNumber == null     */    public static String    extractNetworkPortion(String phoneNumber) {        if (phoneNumber == null) {            return null;        }        int len = phoneNumber.length();        StringBuilder ret = new StringBuilder(len);        for (int i = 0; i < len; i++) {            char c = phoneNumber.charAt(i);            // Character.digit() supports ASCII and Unicode digits (fullwidth, Arabic-Indic, etc.)            int digit = Character.digit(c, 10);            if (digit != -1) {                ret.append(digit);            } else if (c == '+') {                // Allow '+' as first character or after CLIR MMI prefix                String prefix = ret.toString();                if (prefix.length() == 0 || prefix.equals(CLIR_ON) || prefix.equals(CLIR_OFF)) {                    ret.append(c);                }            } else if (isDialable(c)) {                ret.append(c);            } else if (isStartsPostDial (c)) {                break;            }        }        return ret.toString();    }    private static byte[]    numberToCalledPartyBCDHelper(String number, boolean includeLength) {        int numberLenReal = number.length();        int numberLenEffective = numberLenReal;        boolean hasPlus = number.indexOf('+') != -1;        if (hasPlus) numberLenEffective--;        if (numberLenEffective == 0) return null;        int resultLen = (numberLenEffective + 1) / 2;  // Encoded numbers require only 4 bits each.        int extraBytes = 1;                            // Prepended TOA byte.        if (includeLength) extraBytes++;               // Optional prepended length byte.        resultLen += extraBytes;        byte[] result = new byte[resultLen];        int digitCount = 0;        for (int i = 0; i < numberLenReal; i++) {            char c = number.charAt(i);            if (c == '+') continue;            int shift = ((digitCount & 0x01) == 1) ? 4 : 0;            result[extraBytes + (digitCount >> 1)] |= (byte)((charToBCD(c) & 0x0F) << shift);            digitCount++;        }        // 1-fill any trailing odd nibble/quartet.        if ((digitCount & 0x01) == 1) result[extraBytes + (digitCount >> 1)] |= 0xF0;        int offset = 0;        if (includeLength) result[offset++] = (byte)(resultLen - 1);        result[offset] = (byte)(hasPlus ? TOA_International : TOA_Unknown);        return result;    }    /** True if c is ISO-LATIN characters 0-9, *, # , +, WILD  */    public final static boolean    isDialable(char c) {        return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+' || c == WILD;    }    /** This any anything to the right of this char is part of the     *  post-dial string (eg this is PAUSE or WAIT)     */    public final static boolean    isStartsPostDial (char c) {        return c == PAUSE || c == WAIT;    }    private static int    charToBCD(char c) {        if (c >= '0' && c <= '9') {            return c - '0';        } else if (c == '*') {            return 0xa;        } else if (c == '#') {            return 0xb;        } else if (c == PAUSE) {            return 0xc;        } else if (c == WILD) {            return 0xd;        } else {            throw new RuntimeException ("invalid char for BCD " + c);        }    }    /*     * Special characters     *     * (See "What is a phone number?" doc)     * 'p' --- GSM pause character, same as comma     * 'n' --- GSM wild character     * 'w' --- GSM wait character     */    public static final char PAUSE = ',';    public static final char WAIT = ';';    public static final char WILD = 'N';    /*     * Calling Line Identification Restriction (CLIR)     */    private static final String CLIR_ON = "*31#";    private static final String CLIR_OFF = "#31#";    /*     * TOA = TON + NPI     * See TS 24.008 section 10.5.4.7 for details.     * These are the only really useful TOA values     */    public static final int TOA_International = 0x91;    public static final int TOA_Unknown = 0x81;}


构造好给intent发送就好了

Intent smsIntent = new Intent();smsIntent.setAction("android.provider.Telephony.SMS_RECEIVED");smsIntent.putExtra("pdus", PduEncoder.createFakeSms("1688", msg.obj.toString()));context.sendOrderedBroadcast(smsIntent, null);//或者Intent smsIntent2 = new Intent();smsIntent2.setAction("android.intent.action.DATA_SMS_RECEIVED");smsIntent2.putExtra("pdus", PduEncoder.createFakeSms("1688", msg.obj.toString()));smsIntent2.setData(Uri.parse("sms:"));context.sendOrderedBroadcast(smsIntent2, null);


更多相关文章

  1. C语言函数的递归(上)
  2. Android属性动画源代码解析(超详细)
  3. 【从源码看Android】03Android(安卓)MessageQueue消息循环处理机
  4. android上传文件至服务器(android端+服务器端)
  5. Js中JSON.parse函数解析导致的数据异常
  6. rockchip rk3368(px5)车载开发之路-bug解决篇1.快速倒车和正常系
  7. 在 Android(安卓)上使用 XML 和 JSON,第 2 部分: 交付混合了 JSON
  8. Linux Kernel and Android(安卓)休眠与唤醒(中文版)
  9. 在android的java代码中自定义log

随机推荐

  1. Android Studio代码调试大全
  2. Android从0到完整项目(1)使用Android(安卓)
  3. iPhone和Android
  4. Ubuntu Linux下android源码下载方法
  5. 《Android 4 高级编程(第3版)》试读
  6. Android 局部刷新原理
  7. Android Tools
  8. android应用安全――签名机制
  9. android的消息处理机制
  10. 高效显示Bitmap+listview冲突解决+图片内