短消息發送7Bit AscII編碼符號的問題

短消息發送7Bit AscII編碼符號的問題

 

在以前寫的一個通過GSM模塊發送與接收短消息的業務系統已經運行很久了。前兩天檢查接收內容時發現有接收的內容中有亂碼。與發送者聯繫了,瞭解他發送的是一些字母中間有下劃線。因爲接收純字母已經做過測試了。我自己編輯了一條短消息“_”發上去,發現收到的也是亂碼,再發別的AscII字母,完全正常。再發看來問題出在短消息對符號的解碼上。

仔細檢查了一遍解碼程序,沒有發現問題。然後又在網上找了一段別人的解碼代碼,來進行測試,居然發現解碼後的符號也是亂碼。打開數據庫將原始接收的Byte字符串找出來,看到接收到的內容是“11”,十進制爲17,是不可見字符,而“_”的AscII碼是95。又將“_”附近的幾個字符試了一下,居然值都與AscII碼值不相符。

只好Google了,搜了一下“7 bit ”,找到了一個文件”The 7 bit default alphabet”,打開一看,暈,居然有個GSM 03.38規定了1277 Bit字符,與標準的ISO-8859-1不相符。

只好重新寫一個對字符映射表了。本來想用一個數組或Hashtable來做映射,但是有幾個字符居然點用兩個Byte。犧牲點內存與CPU算了,在內存裏建了個數據表,將映射表做到DataTable裏了,然後用DataViewRowFilter來查找。可慢了一點,但用起來方便。

源碼如下:

    public class Gsm7BitEncoding
    {
        DataTable dt7BitAlphabet = new DataTable();
        DataView dv;
        private static Gsm7BitEncoding _gsm7bit = new Gsm7BitEncoding();
        public static Gsm7BitEncoding GetInstance()
        {
            return _gsm7bit;
        }

        public Gsm7BitEncoding()
        {
            //添加列
            DataColumn dc=new DataColumn("I_Pre",typeof(byte));
            dc.DefaultValue=0;
            dt7BitAlphabet.Columns.Add(dc);


            dc = new DataColumn("I_GsmChar", typeof(byte));
            dc.DefaultValue = 0;
            dt7BitAlphabet.Columns.Add(dc);


            dc = new DataColumn("I_AscIIChar", typeof(byte));
            dc.DefaultValue = 0;
            dt7BitAlphabet.Columns.Add(dc);
           
#region 添加數據行
          dt7BitAlphabet.Rows.Add(new object[] { 0,0 , 64   });               
            dt7BitAlphabet.Rows.Add(new object[] { 0,1 , 163  });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,2 , 36   });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,3 , 165  });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,4 , 232  });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,5 , 233  });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,6 , 249  });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,7 , 236  });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,8 , 242  });
            dt7BitAlphabet.Rows.Add(new object[] { 0, 9, 199 });    
            dt7BitAlphabet.Rows.Add(new object[] { 0,10 , 10   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,11 , 216  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,12 , 248  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,13 , 13   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,14 , 197  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,15 , 229  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,16 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,17 , 95   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,18 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,19 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,20 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,21 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,22 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,23 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,24 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,25 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,26 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,27 , 0    });  
            dt7BitAlphabet.Rows.Add(new object[] {27,10 , 12   }); 
            dt7BitAlphabet.Rows.Add(new object[] {27,20 , 94   }); 
            dt7BitAlphabet.Rows.Add(new object[] {27,40 , 123   });
            dt7BitAlphabet.Rows.Add(new object[] {27,41 , 125   });
            dt7BitAlphabet.Rows.Add(new object[] {27,47 , 92   }); 
            dt7BitAlphabet.Rows.Add(new object[] {27,60 , 91   }); 
            dt7BitAlphabet.Rows.Add(new object[] {27,61 , 126   });
            dt7BitAlphabet.Rows.Add(new object[] {27,62 , 93   }); 
            dt7BitAlphabet.Rows.Add(new object[] {27,64 , 124   });
            dt7BitAlphabet.Rows.Add(new object[] {27,101 , 164   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,28 , 198  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,29 , 230  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,30 , 223  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,31 , 201  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,32 , 32   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,33 , 33   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,34 , 34   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,35 , 35   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,36 , 164  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,37 , 37   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,38 , 38   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,39 , 39   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,40 , 40   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,41 , 41   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,42 , 42   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,43 , 43   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,44 , 44   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,45 , 45   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,46 , 46   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,47 , 47   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,48 , 48   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,49 , 49   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,50 , 50   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,51 , 51   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,52 , 52   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,53 , 53   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,54 , 54   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,55 , 55   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,56 , 56   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,57 , 57   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,58 , 58   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,59 , 59   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,60 , 60   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,61 , 61   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,62 , 62   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,63 , 63   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,64 , 161  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,65 , 65   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,66 , 66   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,67 , 67   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,68 , 68   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,69 , 69   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,70 , 70   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,71 , 71   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,72 , 72   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,73 , 73   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,74 , 74   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,75 , 75   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,76 , 76   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,77 , 77   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,78 , 78   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,79 , 79   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,80 , 80   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,81 , 81   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,82 , 82   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,83 , 83   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,84 , 84   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,85 , 85   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,86 , 86   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,87 , 87   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,88 , 88   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,89 , 89   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,90 , 90   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,91 , 196  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,92 , 214  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,93 , 209  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,94 , 220  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,95 , 167  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,96 , 191  });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,97 , 97   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,98 , 98   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,99 , 99   });  
            dt7BitAlphabet.Rows.Add(new object[] { 0,100 , 100   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,101 , 101   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,102 , 102   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,103 , 103   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,104 , 104   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,105 , 105   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,106 , 106   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,107 , 107   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,108 , 108   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,109 , 109   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,110 , 110   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,111 , 111   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,112 , 112   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,113 , 113   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,114 , 114   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,115 , 115   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,116 , 116   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,117 , 117   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,118 , 118   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,119 , 119   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,120 , 120   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,121 , 121   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,122 , 122   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,123 , 228   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,124,124   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,125,125   });
            dt7BitAlphabet.Rows.Add(new object[] { 0,126,126   });
#endregion

            dv = dt7BitAlphabet.DefaultView;
        }
        /// <summary>
        /// 獲取AscII字符串的Gsm7Bit字符編碼的長度
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public int GetByteCount(string s)
        {
            byte[] gsmBytes = GetBytes(s);

            return gsmBytes.Length;
        }
        /// <summary>
        /// 將AscII字符串轉換爲Gsm7Bit字符數據
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public byte[] GetBytes(string s)
        {
            byte[] ascBts;
            List<byte> gsmBts=new List<byte>();
            ascBts = ASCIIEncoding.ASCII.GetBytes(s);
            for (int i = 0; i < ascBts.Length; i++)
            {
               dv.RowFilter = "I_AscIIChar=" + ascBts[i].ToString();
                if (dv.Count>0)
                {
                    byte pre = (byte)dv[0][0];
                    byte gsmchar = (byte)dv[0][1];
                   
                    if (pre==27)
                    {
                        gsmBts.Add(27);
                    }
                    gsmBts.Add(gsmchar);
                }
            }
            return gsmBts.ToArray();
        }
        /// <summary>
        /// 從GSM7Bit字符數據轉換爲AscII字符串
        /// </summary>
        /// <param name="gsmBytes"></param>
        /// <returns></returns>
        public string GetString(byte[] gsmBytes)
        {
            StringBuilder sb = new StringBuilder();
            string condition = "";
            for (int i = 0; i < gsmBytes.Length; i++)
            {
                if (gsmBytes[i] == 27)
                {
                    condition = " I_Pre=27 and ";
                    i++;
                    condition += " I_GsmChar=" + gsmBytes[i].ToString();
                }
                else
                {
                    condition = "I_Pre=0 and I_GsmChar=" + gsmBytes[i].ToString();
                }
                dv.RowFilter = condition;

                if (dv.Count>0)
                {
                    System.Diagnostics.Debug.Assert((byte)dv[0][2] != 0);
                    sb.Append((char)(byte)dv[0][2]);
                }
            }
            return sb.ToString();
        }
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章