天天看點

關于短信内容格式及壓縮方法

 

author: scruffybear

release time: 29/08/2007

 七月份做警務通的項目,涉及到對已有的短信内容進行修改的問題,也就是所說的對COS打更新檔修改短信内容的問題,聯系本項目在這裡對G網短信和C網短信的格式和壓縮方法進行簡單介紹。

1,G網短信的一般格式

   G網短信格式完全遵守《GSM03.40規範》,是以很容易通過現有規範對現有短信進行解析。卡片按照《GSM11.14規範》來組織短信,發送短信的command tag為‘13’,SMS TPDU tag為‘0B/8B’,更詳細内容請參見該規範,現用一條具體短信解釋格式如下:

   Fetch指令取得短信内容:

   A01200002FSWD02D81030A130082028183850D8077ED4FE153D190014E2D20268B13010008819494881100080812345678123456789000

      Command Details   01/81 03 0A(Command number) 13(command tag) 00(Command Qualifier)    此項是強制的(Mandatory)

      Device identities 02/82 02 81(SIM) 83(Network) 此項是強制的(Mandatory)

      Alpha identifier  05/85 0D 8077ED4FE153D190014E2D2026(短信發送中…) 此項應該是可選的(Optional)

      Address tag   此例中沒有,舉例:06/86 08FFFFFFFFFFFFFFFF   此項應該是可選的(Optional)

      SMS TPDU tag  0B/8B 13 01000881949488110008081234567812345678(此項内容在GSM03.40規範中解釋) 

   SMS TPDU内容由《GSM03.40規範》進行解釋,具體可參見該規範9.2節,Service Provided by the SM-TL(The Short Message Transfer Layer),現僅對具體本條短信的TPDU進行解釋,内容如上:0B/8B 13 01000881949488110008081234567812345678,此短信為SUBMIT類型:

      TP-MTI(TP-Message-Type-Indicator)等, 01,bit1,bit0最低兩位為01,表示短信内容為SMS-SUBMIT (in the direction MS to SC),bit4,bit3為00,表示短信中無TP-VP字段:0 0 TP-VP field not present

      TP-MR(TP-Message-Reference) 00

      TPDA(TP-Destination-Address) 088194948811,TPDA的長度為(len+1)/2+1,在本例中,為(8+1)/2+1=5  

      TP-PID(TP-Protocol-Identifier) 00

      TP-DCS(TP-Data-Coding-Scheme) 08

      TP-VP(TP-Validity-Period) 此短信中無,該項表示短信的有效期。

      TP-UDL+TPUD(TP-User-Data-Length+TP-User-Data) 081234567812345678

      注意:TPUDL長度為實作壓縮前的長度。

    以上說明針對具體短信,更多情況請參照相應規範,在此不贅述。          

2,G網短信的壓縮及彙編實作

   由于更新檔中需要對G網短信做壓縮,而且不友善調用已有函數,故用彙編實作了G網的短信壓縮。

   G網短信壓縮格式在TP-DCS中訓示,TP-DCS在《GSM03.38》中有說明,一般都采用将7bit編碼壓縮成8bit編碼方式,這種壓縮方式也在《GSM03.38》中有詳細說明。

   壓縮編碼方式将8位元組的7bit編碼壓縮成7位元組的8bit編碼,也就是說160位元組長短信可以壓縮為140位元組的短信,壓縮了20位元組,具體壓縮方法如下: 

   原始的8位元組未壓縮編碼如下:

      - bits number:

        6    5   4   3   2   1   0

        1a 1b 1c 1d 1e 1f 1g

        2a 2b 2c 2d 2e 2f  2g

        3a 3b 3c 3d 3e 3f  3g

        4a 4b 4c 4d  4e 4f 4g

        5a 5b 5c  5d 5e 5f 5g

        6a 6b  6c 6d 6e 6f 6g 

        7a 7b 7c 7d 7e 7f 7g

        8a 8b 8c 8d 8e 8f 8g

  經過壓縮後的8bit編碼如下:

    - eight characters in seven octets:

    - bits number: 

      7   6   5   4   3   2   1   0

     2g 1a 1b 1c 1d 1e 1f 1g

     3f 3g 2a 2b 2c 2d 2e 2f

     4e 4f 4g 3a 3b 3c 3d 3e

     5d 5e 5f 5g 4a 4b 4c 4d

     6c 6d 6e 6f 6g 5a 5b 5c

     7b 7c 7d 7e 7f 7g 6a 6b

     8a 8b 8c 8d 8e 8f 8g 7a

    從以上的壓縮方法可以看出,第一個壓縮後位元組是第一個7bit在最高位加上第二個7bit的最低位,第二個壓縮位元組是第二個7bit的高六位加上第三個7bit的低兩位,依次類推。 第七個壓縮後位元組(最後一個壓縮位元組)是第七個7bit的最高位加上整個第八個7bit的七位。這樣就實作了将8個位元組的7bit編碼壓縮成7個位元組的8bit編碼。

    舉一個具體的例子,字元串3132333435363738是7bit編碼,現壓縮成8bit編碼。

    3132333435363738轉換為bit為00110001(31) 00110010(32) 00110011(33) 00110100(34) 00110101(35) 00110110(36) 00110111(37) 00111000(38),進行轉換,過程如下:

    a,轉換31,32的最低位到31的最高位,可以看到31不變,第一個壓縮後位元組為31

    b,轉換32,32由于取了最低位,相當于向右移了一位,為00011001,将33的低兩位放在右移一位的31高位上,也就為11011001,即D9。

    c,轉換33,33由于取了低兩位,相當于向右移了兩位,為00001100,将34的低三位放在右移兩位的33高位上,也就為10001100,即8C。

    d,轉換34,34由于取了低三位,相當于向右移了三位,為00000110,将35的低四位放在右移三位的34高位上,也就為01010110,即56。

    e,轉換35,35由于取了低四位,相當于向右移了四位,為00000011,将36的低五位放在右移四位的35高位上,也就為10110011,即B3。

    f,轉換36,36由于取了低五位,相當于向右移了五位,為00000001,将37的低六位放在右移五位的36高位上,也就為11011101,即DD。

    g,轉換37,37由于取了低六位,相當于向右移了六位,為00000000,将整個38的七位放在右移六位的37高位上,也就是1110000,即70。

    到此7位編碼的3132333435363738壓縮為了7位元組的31D98C56B3DD70,也就是說壓縮掉了一位元組。

    在進行編碼實作時,可以将壓縮前的短信每8位元組為一組進行處理,處理為壓縮後的七位元組,這樣形成外層循環。循環次數為短信長度除以8再向上取整,例如11/8=1, 1+1 = 2,也就是經過兩次循環。進行内層循環處理時,需要進行七次循環,循環到n(0<n<8)次時,首先将目前位元組右移n-1位,取後一位元組的低n位,放在目前位元組右移n-1位後的高n位,這樣就可以完成對8位元組的壓縮,進而完成對整個短信的壓縮。

    由于涉及到很多相關的前後環境變量的處理,這裡僅列出彙編實作的架構(此處為标準51彙編,雙DPTR)如下:

; DPTR和DPTR1都指向短信開始處,R1中存放外層循環變量,内層循環變量為R2,初始值為1,R3中存放需要轉換字元的總長度,并已設定好。 
      ; 實際上每一次内層循環,都是兩位元組一處理,這裡将兩位元組分别稱為第一位元組和第二位元組。 
      ; 每一次層循環過程是取第二位元組的低R2放在第一位元組的高R2位上,然後将第二位元組右移R2位後作為下一次内層循環的第一位元組。 
     MOVX  A ,  @DPTR
    MOV   R6 ,  A       ; 在進行第一次處理之前預設R6為第一位元組内容。 
   out_transbegin:     ; 外層循環開始處,循環[len/8](注意是向上取整)次。    
     MOV  R2 ,   # 1       ; 進行外層循環之前,需要将内層循環變更R2設定為1 
   transbegin:        ; 内層循環開始處,循環7次。 
     MOV  A ,   R6      ; the 2nd number of  last  loop as the first number. 
     MOV  R5 ,   A    ; R5  store the 1st number. 
     INC  DPTR
    MOVX  A ,   @DPTR
    MOV  R6 ,   A    ; R6  store   2rd  number. 
     
    MOV  R0 ,   A    ; 将第二個位元組存放在R0中,以備後用。 
     
    MOV  A ,   R2      ; 2*2*...*2(R2個2)-1 
     MOV  R7 ,   A     
    LCALL  POWER2    ; POWER2為2的N次方,N從R7傳入,POWER2函數實作很簡單,這裡不列出。 
     CLR  C
    SUBB  A ,   #01H      ; 2*2*...*2-1即2的R2次方減一,2exp(R2)-1 
     ANL  A ,   R6   ;   2nd number & 111...11, 取後一位元組的低R2位,例如第一次循環,取最低位。 2exp(1)-1 = 1, 取最低位,如果為2exp(2)-1=3,取最低兩位。 
     MOV  R6 ,   A    ; R6 store the anl result   
     
    MOV  A ,   # 8       ; 計算8-R2,取了第二個位元組的低R2位後,再左移(8-R2)位,最後與第一個位元組進行或操作。 
     CLR  C
    SUBB  A ,   R2     ; 8-R2 
     MOV  R7 ,   A      ; R7是輸入參數,即左移次數。 
     MOV  A ,   R6      ; ANL操作的後再左移(8-R2)位,放在第一個位元組的高位。 
     LCALL  LFRotateN    ; 左位移(8-R2)位,LFRotateN很簡單,不列出,結果放在A裡。 
     
    ORL  A ,   R5    ; 進行或操作,将第二個位元組的低R2位放在第一個位元組的高R2位上。      
     MOVX  @DPTR1 ,   A         ; 結果存放在DPTR1所指的地方。 
     
    MOV  A ,   R2
    MOV  R7 ,   A     ; 右移次數。 
     MOV  A ,   R0     ; 前面儲存的第二位元組在R0中,這裡右移R2位,作為下一次循環的第一位元組。 
     LCALL  RTRotateN     ; 右移R2位操作,RTRotateN很簡單,不列出,結果放在A裡。 
     MOV  R6 ,   A     ; R6作為下一次循環的第一位元組。     
     
    
    INC DPTR1     ; 寫指針DPTR1加1 
     INC R2        ; 内層循環變量加1 
     
    MOV  A ,   R3    ; R3  is the len 
     CLR  C
    SUBB  A ,   # 1 
    MOV  R3 ,   A     ; R3也就是轉換的總長度減一, R3=R3-1 
     JZ  transend    ; 如果長度為0,則表示已經處理完所有位元組,即出。    
     CJNE  R2 ,   # 8 ,  transbegin    ; 循環範圍為1~7 
     
    INC  DPTR      ; outer loop proceed,進入下一次外層循環前的準備工作。 
     MOVX  A ,   @DPTR
    MOV  R6 ,   A     ; 進入下一個8位元組處理之前預設第一位元組為R6 
     
    MOV  A ,   R3    ; R3是短信長度,進入下一次處層循環時,R3長度也要減1,處理的是下一個8位元組的頭兩個位元組。 
     CLR  C
    SUBB  A ,   # 1 
    MOV  R3 ,   A
    JZ  transend    
    
    DJNZ  R1 ,   out_transbegin    ; loop [len/8] times, 如果R1沒減到0,則進入到下層循環。         
                 
  transend:   
      
關于短信内容格式及壓縮方法