⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaultalphabetencoding.java

📁 SMPP(点到点短消息协议)的java实现
💻 JAVA
字号:
package ie.omk.smpp.util;import java.io.ByteArrayOutputStream;/** * This class encodes and decodes Java Strings to and from the SMS default * alphabet. It also supports the default extension table. The default alphabet * and it's extension table is defined in GSM 03.38. */public class DefaultAlphabetEncoding extends ie.omk.smpp.util.AlphabetEncoding {    private static final int DCS = 0;    public static final int EXTENDED_ESCAPE = 0x1b;    /** Page break (extended table). */    public static final int PAGE_BREAK = 0x0a;    private static final char[] CHAR_TABLE = {        '@', '\u00a3', '$', '\u00a5', '\u00e8', '\u00e9', '\u00f9', '\u00ec',        '\u00f2', '\u00c7', '\n', '\u00d8', '\u00f8', '\r', '\u00c5', '\u00e5',        '\u0394', '_', '\u03a6', '\u0393', '\u039b', '\u03a9', '\u03a0', '\u03a8',        '\u03a3', '\u0398', '\u039e', ' ', '\u00c6', '\u00e6', '\u00df', '\u00c9',        ' ', '!', '"', '#', '\u00a4', '%', '&', '\'',        '(', ')', '*', '+', ',', '-', '.', '/',        '0', '1', '2', '3', '4', '5', '6', '7',        '8', '9', ':', ';', '<', '=', '>', '?',        '\u00a1', 'A', 'B', 'C', 'D', 'E', 'F', 'G',        'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',        'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',        'X', 'Y', 'Z', '\u00c4', '\u00d6', '\u00d1', '\u00dc', '\u00a7',        '\u00bf', 'a', 'b', 'c', 'd', 'e', 'f', 'g',        'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',        'p', 'q', 'r', 's', 't', 'u', 'v', 'w',        'x', 'y', 'z', '\u00e4', '\u00f6', '\u00f1', '\u00fc', '\u00e0',    };    /**     * Extended character table. Characters in this table are accessed by the     * 'escape' character in the base table. It is important that none of the     * 'inactive' characters ever be matchable with a valid base-table     * character as this breaks the encoding loop.     *      * @see #EXTENDED_ESCAPE     */    private static final char[] EXT_CHAR_TABLE = {            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, '^', 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            '{', '}', 0, 0, 0, 0, 0, '\\',            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, '[', '~', ']', 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, '\u20ac', 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,            0, 0, 0, 0, 0, 0, 0, 0,    };    private static final DefaultAlphabetEncoding INSTANCE = new DefaultAlphabetEncoding();    public DefaultAlphabetEncoding() {        super(DCS);    }    /**     * Get the singleton instance of DefaultAlphabetEncoding.     * @deprecated     */    public static DefaultAlphabetEncoding getInstance() {        return INSTANCE;    }    /**     * Decode an SMS default alphabet-encoded octet string into a Java String.     */    public String decodeString(byte[] b) {        if (b == null) {            return "";        }        char[] table = CHAR_TABLE;        StringBuffer buf = new StringBuffer();        for (int i = 0; i < b.length; i++) {            int code = (int) b[i] & 0x000000ff;            if (code == EXTENDED_ESCAPE) {                // take next char from extension table                table = EXT_CHAR_TABLE;            } else {                buf.append((code >= table.length) ? '?' : table[code]);                // Go back to the default table.                table = CHAR_TABLE;            }        }        return buf.toString();    }    /**     * Encode a Java String into a byte array using the SMS Default alphabet.     */    public byte[] encodeString(String s) {        if (s == null) {            return new byte[0];        }        char[] c = s.toCharArray();        ByteArrayOutputStream enc = new ByteArrayOutputStream(256);        for (int loop = 0; loop < c.length; loop++) {            int search = 0;            for (; search < CHAR_TABLE.length; search++) {                if (search == EXTENDED_ESCAPE) {                    continue;                }                if (c[loop] == CHAR_TABLE[search]) {                    enc.write((byte) search);                    break;               }                if (c[loop] == EXT_CHAR_TABLE[search]) {                    enc.write((byte) EXTENDED_ESCAPE);                    enc.write((byte) search);                    break;               }            }            if (search == CHAR_TABLE.length) {                // A '?' character.                enc.write(0x3f);            }        }        return enc.toByteArray();    }    public int getEncodingLength() {        return 7;    }    /**     * Pack a byte array according to the GSM bit-packing algorithm.     * The GSM specification defines a simple compression mechanism for its     * default alphabet to pack more message characters into a smaller space.     * Since the alphabet only contains 128 symbols, each one can be represented     * in 7 bits. The packing algorithm squeezes the bits for each symbol     * "down" into the preceeding byte (so bit 7 of the first byte actually     * contains bit 0 of the second symbol in a default alphabet string, bits     * 6 and 7 in the second byte contain bits 0 and 1 of the third symbol etc.)     * Since the maximum short message length is 140 <b>bytes</b>, you save     * one bit per byte using the default alphabet giving you a total of     * 140 + (140 / 8) = 160 characters to use. This is where the 160 character     * limit comes from in SMPP packets.     * <p>     * Having said all that, most SMSCs do <b>NOT</b> use the packing     * algorithm when communicating over TCP/IP. They either use a full     * 8-bit alphabet such as ASCII or Latin-1, or they accept the default     * alphabet in its unpacked form. As such, you will be unlikely to     * need this method.     * </o>     * @param unpacked The unpacked byte array.      * @return A new byte array containing the bytes in their packed form.     */    public byte[] pack(byte[] unpacked) {        int packedLen = unpacked.length - (unpacked.length / 8);        byte[] packed = new byte[packedLen];        int pos = 0;        int i = 0;        while (i < unpacked.length) {            int jmax = (i + 7) > unpacked.length ? unpacked.length - i : 7;            int mask = 0x1;            for (int j = 0; j < jmax; j++) {                int b1 = (int) unpacked[i + j] & 0xff;                int b2 = 0x0;                try {                    b2 = (int) unpacked[i + j + 1] & mask;                } catch (ArrayIndexOutOfBoundsException x) {                }                packed[pos++] = (byte) ((b1 >>> j) | (b2 << (8 - (j + 1))));                mask = (mask << 1) | 1;            }            i += 8;        }        return packed;    }    /**     * Unpack a byte array according to the GSM bit-packing algorithm.     * Read the full description in the documentation of the     * <code>pack</code> method.     * @see #pack(byte[])     * @param packed The packed byte array.     * @return A new byte array containing the unpacked bytes.     */    public byte[] unpack(byte[] packed) {        int unpackedLen = (packed.length * 8) / 7;        byte[] unpacked = new byte[unpackedLen];        int pos = 0;        int i = 0;        while (i < packed.length) {            int mask = 0x7f;            int jmax = (i + 8) > packed.length ? (packed.length - i) : 8;            for (int j = 0; j < jmax; j++) {                int b1 = (int) packed[i + j] & mask;                int b2 = 0x0;                try {                    b2 = (int) packed[(i + j) - 1] & 0x00ff;                } catch (ArrayIndexOutOfBoundsException x) {                }                unpacked[pos++] = (byte) ((b1 << j) | (b2 >>> (8 - j)));                mask >>= 1;            }            i += 7;        }        return unpacked;    }    public String toString() {        final String fmt = "{0,number,000}: {1}  ";        final Object[] args = new Object[2];                StringBuffer b = new StringBuffer(256);        b.append("Table size: ").append(CHAR_TABLE.length).append('\n');        for (int i = 0; i < 16; i++) {            for (int j = 0; j < 8; j++) {                int pos = i + (16 * j);                args[0] = new Integer(pos);                if (CHAR_TABLE[pos] == '\r') {                    args[1] = "CR";                } else if (CHAR_TABLE[pos] == '\n') {                    args[1] = "LF";                } else if (CHAR_TABLE[pos] == ' ') {                    args[1] = "SP";                } else {                    args[1] = " " + CHAR_TABLE[pos];                }                b.append(java.text.MessageFormat.format(fmt, args));            }            b.append('\n');        }        return b.toString();    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -