PBOC/EMV之TLV編碼與解碼

原處:http://blog.csdn.net/pony_maggie/article/details/5270548


PBOC的IC卡大部分數據都是TLV格式的. EMV的手冊簡單的編碼規則說明. 我下面很詳細的分析TLV的編碼格式並給出相應的TLV解碼的僞代碼.

 

TLV是tag, length和value的縮寫.一個基本的數據元就包括上面三個域. Tag唯一標識該數據元, length是value域的長度. Value就是數據本身了. 舉個例子, 下面是一個tlv格式的AID(應用標識符)字節串”9F0607A0000000031010”, 其中9F06是tag, 07是長度, A0000000031010就是AID本身的值了.

 

開發人員應該關心的是,如果有類似上面這樣的一串TLV編碼的字節串從卡片傳過來, 怎麼樣從中提取我們想要的數據? 這就就是TLV解碼的問題了.

 

其中BER-TLV編碼是ISO定義一種規範, 然後到了PBOC/EMV裏被簡化了. 舉一個例子, tag域在ISO裏可以有多個字節,而PBOC/EMV裏規定只用前兩個字節. 我下面要講的TLV解碼就是基於PBOC/EMV的簡化版本.

 

首先看一下tag域是怎樣編碼的. Tag域最多佔兩個字節. 編碼規則如下面兩幅圖

 

圖1
 圖2

 

 

解釋一下這兩幅圖. 第一個圖是第一個字節的編碼規則. b8和b7兩位標識tag所屬類別. 這個可以暫時不用理.  b6決定當前的TLV數據是一個單一的數據和複合結構的數據. 複合的TLV是指value域裏也包含一個或多個TLV, 類似嵌套的編碼格式. b5~b1如果全爲1,則說明這個tag下面還有一個子字節. 佔兩個字節, 否則tag佔一個字節.


第二幅圖是說明如果tag佔用兩個字節, 第二個字節的編碼格式. B8決定tag是否還有後緒的字節存在,因爲前面說過,PBOC/EMV裏的tag最多佔兩個字節, 所以該位保持爲0.

 

清楚了上面tag編碼格式,可很容易寫出tag域解碼的代碼了. 假設,終端接收到字節串,這個字節串保存在tlvData的字節數組裏, 僞代碼如下:

[cpp] view plain copy
  1. if ( (tlvData[i]&0x20) != 0x20)//單一結構  
  2.   
  3. {  
  4.   
  5.       if ( (tlvData[i]&0x1f) == 0x1f)//tag兩字節  
  6.   
  7.        {  
  8.   
  9.              tagIndex++;  
  10.   
  11.                       
  12.   
  13.              //解析length域  
  14.   
  15.                //解析value域  
  16.   
  17.        }  
  18.   
  19.      else//tag單字節  
  20.   
  21.       {  
  22.   
  23.           //解析length域  
  24.   
  25.             //解析value域  
  26.   
  27.       }  
  28.   
  29. }  
  30.   
  31.  else//複合結構  
  32.   
  33.  {  
  34.   
  35.           //複合結構可以考慮用遞歸的方法來實現.  
  36.   
  37.  }  

Length域的編碼比較簡單,最多有四個字節, 如果第一個字節的最高位b8爲0, b7~b1的值就是value域的長度. 如果b8爲1, b7~b1的值指示了下面有幾個子字節. 下面子字節的值就是value域的長度.Value域的編碼格式要根據具體的value所表示的數據元決定. 比如AID是由RID+PIX構成等. 這個不詳述. 有了上面的知識,基本上可以寫一個TLV解碼器出來了.    

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