中國移動信令XDR TBCD編碼與解碼
阿新 • • 發佈:2019-01-02
最近遇到TBCD解碼、編碼的問題,經過一番查詢。發現其實很簡單。原理其實就是把TBCD的編碼,高4位和第4位互換,然後每4位轉換為十進位制。F為空即可。
例如:
TBCD編碼: 31 55 40 20 79 F9
解碼後原始: 13 55 04 02 97 9 (號碼隨便敲得,沒有任何含義,如有雷同純屬巧合)
提供一個Java的演算法實現給大家:
// package tbcd; /** * This sample code demonstrates how a character string can be convered to * a TBCD (Telephony Binary Coded Decimal) string and vice versa. */ public class TBCDUtil { private static String cTBCDSymbolString = "0123456789*#abc"; private static char[] cTBCDSymbols = cTBCDSymbolString.toCharArray(); public static void main(String[] args) { if (args.length == 0) return; byte[] tbcd = parseTBCD(args[0]); System.out.println("TBCD as octets: " + dumpBytes(tbcd)); System.out.println("TBCD octets decoded: " + toTBCD(tbcd)); } /* * This method converts a TBCD string to a character string. */ public static java.lang.String toTBCD (byte[] tbcd) { int size = (tbcd == null ? 0 : tbcd.length); StringBuffer buffer = new StringBuffer(2*size); for (int i=0; i<size; ++i) { int octet = tbcd[i]; int n2 = (octet >> 4) & 0xF; int n1 = octet & 0xF; if (n1 == 15) { throw new NumberFormatException("Illegal filler in octet n=" + i); } buffer.append(cTBCDSymbols[n1]); if (n2 == 15) { if (i != size-1) throw new NumberFormatException("Illegal filler in octet n=" + i); } else buffer.append(cTBCDSymbols[n2]); } return buffer.toString(); } /* * This method converts a character string to a TBCD string. */ public static byte[] parseTBCD (java.lang.String tbcd) { int length = (tbcd == null ? 0:tbcd.length()); int size = (length + 1)/2; byte[] buffer = new byte[size]; for (int i=0, i1=0, i2=1; i<size; ++i, i1+=2, i2+=2) { char c = tbcd.charAt(i1); int n2 = getTBCDNibble(c, i1); int octet = 0; int n1 = 15; if (i2 < length) { c = tbcd.charAt(i2); n1 = getTBCDNibble(c, i2); } octet = (n1 << 4) + n2; buffer[i] = (byte)(octet & 0xFF); } return buffer; } private static int getTBCDNibble(char c, int i1) { int n = Character.digit(c, 10); if (n < 0 || n > 9) { switch (c) { case '*': n = 10; break; case '#': n = 11; break; case 'a': n = 12; break; case 'b': n = 13; break; case 'c': n = 14; break; default: throw new NumberFormatException("Bad character '" + c + "' at position " + i1); } } return n; } /* Hex chars */ private static final byte[] HEX_CHAR = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /* * Helper function that dumps an array of bytes in the hexadecimal format. */ public static final String dumpBytes( byte[] buffer ) { if ( buffer == null ) { return ""; } StringBuffer sb = new StringBuffer(); for ( int i = 0; i < buffer.length; i++ ) { sb.append( "0x" ).append( ( char ) ( HEX_CHAR[( buffer[i] & 0x00F0 ) >> 4] ) ).append( ( char ) ( HEX_CHAR[buffer[i] & 0x000F] ) ).append( " " ); } return sb.toString(); } }