PBOC EMV中TLV的構造和解析

2021-08-09 13:14:19 字數 4604 閱讀 5364

ber-tlv資料物件編碼

根據 iso/iec 8825 的定義,乙個 ber-tlv 資料物件包括 2-3 個連續資料域:

l 標籤域( tag)包括乙個或多個連續位元組。它定義一種類別、型別和乙個數字。本規範規定的資料物件的標籤域用乙個或二個位元組編碼。

l 長度域( length)包括乙個或多個連續位元組。它定義了接下來乙個域的長度。本規範規定的資料物件的長度用乙個、或二個位元組編碼。

l值域( value)定義資料物件的值。如果l= 『 00』 ,則值域不存在。

先看看tag域的編碼:

表 b-2 根據 iso/iec 8825 定義了當標籤號=31(即第一位元組的b5- b1 位為『 11111』 )時,ber-tlv 標籤跟隨位元組的編碼規則。即tag域擴充套件到下乙個位元組。

當b8為1時,還需要擴充套件。但emv文件中說明,tag域最多占用兩個位元組。

length域的規範:

當長度域的最高位元組的b8 位為 0 時,長度域僅有乙個位元組。 b7 到 b1 位的值為值域的位元組數。長度域的範圍為1 到 127。

當長度域的最高位元組的 b8 位位 1 時,緊接的 b7 到 b1 位的值為長度域最高位元組後跟隨的長度位元組數。後續位元組的整數值為值域的位元組數。要表示 255 個位元組以下的值域,至少需要2 個位元組。

value域的規範:

基本ber-tlv 資料物件的值域是乙個資料元。資料元是帶標識(標籤)的最小資料域。

復合ber-tlv 資料物件包括乙個標籤、乙個長度和乙個值域,其值域由乙個和多個ber-tlv資料物件組成。

下面是tlv**的例子:

tlv結構體:

[cpp]view plain

copy

print?

//建立tlv結構體

typedef

struct tlventity  

tlv, *ptlv;  

構造tlv的函式:

[cpp]view plain

copy

print?

//構造tlv

void tlvconstruct(unsigned char *buffer,            //tlv字串    

unsigned int bufferlength,        //tlv字串長度

ptlv ptlventity,                  //tlv指標

unsigned int& entitysize          //tlv結構數量,解析時用到

)    

else

}  else

else

//分析子tlv中的tag

int subtlvlength = 0;           //子tlv長度

unsigned char * temp;           //子tlv所包含的資料

//先判斷length域的長度,length域位元組如果最高位為1,後續位元組代表長度,為0,1--7位代表資料長度

if ((buffer[currentindex] & 0x80) == 0x80)  

//申請一段subtlvlength大小的記憶體存放該tlv的內容

temp = (unsigned char *)malloc(subtlvlength);  

memcpy(temp, buffer + currentindex + 1 + lengthsize, subtlvlength);  

}  else

temp[subtlvlength] = 0;  

unsigned int osize;//輸出有多少個同等級的子tlv,解析時也應該用到

//不清楚子tlv同等級的tlv有多少個,申請100tlv大小的記憶體肯定夠用

ptlventity[currenttlvindex].subtlventity = (ptlv)malloc(sizeof(tlv[100]));  

tlvconstruct(temp, subtlvlength, ptlventity[currenttlvindex].subtlventity, osize);  

ptlventity[currenttlvindex].subtlvnum = osize; //填入子tlv的數量

}  currentstatus = 'l';  

break;  

case

'l':  

//判斷長度位元組的最高位是否為1,如果為1,則該位元組為長度擴充套件位元組,由下乙個位元組開始決定長度

if ((buffer[currentindex] & 0x80) == 0x80)  

ptlventity[currenttlvindex].length = (unsigned char *)malloc(lengthsize);  

memcpy(ptlventity[currenttlvindex].length, buffer + currentindex, lengthsize);  

ptlventity[currenttlvindex].length[lengthsize] = 0;  

ptlventity[currenttlvindex].lengthsize = lengthsize;  

currentindex += lengthsize;  

}  else

currentstatus = 'v';  

break;  

case

'v':  

ptlventity[currenttlvindex].value = (unsigned char *)malloc(valuesize);  

memcpy(ptlventity[currenttlvindex].value, buffer + currentindex, valuesize);  

ptlventity[currenttlvindex].value[valuesize] = 0;  

currentindex += valuesize;  

//進入下乙個tlv構造迴圈

currenttlvindex += 1;  

currentstatus = 't';  

break;  

}  }  

entitysize = currenttlvindex;  

}  

解析tlv的函式:

[cpp]view plain

copy

print?

// 解析tlv

bool tlvparseandfinderror(  

ptlv ptlventity,                    //輸入的tlv結構體

unsigned int entitysize,            //tlv結構體的數量

unsigned char* buffer,              //輸出的字串

unsigned int& bufferlength          //字串的長度

)    

if(valuesize > 127)                                  //還原length  當最高位為1的情況

memcpy(buffer + currentindex, entity.length, entity.lengthsize);    //解析length

currentindex += entity.lengthsize;  

//判斷是否包含子巢狀tlv

if(entity.subtlventity == null)  

else

currenttlvindex++;  

}  buffer[currentindex] = 0;  

bufferlength = currentindex;  

return true;  

}  

測試的函式:

[cpp]view plain

copy

print?

unsigned char requestbuf = ;  

int main(int argc, char* argv)  

if(strncmp((char*)parsebuf, (char*)requestbuf, sizeof(requestbuf)) == 0)  

else

printf("hello world!\n");  

return 0;  

}  

本文借鑑於:原文的**有些小問題,本文修正了,另外**注釋更加得詳細。

c 中的建構函式和拷貝建構函式

c 的類有六個預設成員函式,我今天介紹其中的兩個,乙個是建構函式另乙個是拷貝建構函式。建構函式用於當類的物件被建立時,給它分配記憶體空間,並且由編譯器自動呼叫建構函式對類物件進行初始化工作。建構函式的函式名與類名相同,沒有返回型別。下面是乙個例子 class string private char ...

C 中的拷貝構造,賦值和移動構造

在說明這幾個名詞時,我們需要定義乙個測試類person,person類的測試環境為vs2013 一般情況下,在物件宣告時用拷貝建構函式對物件進行初始化 在編譯器進行優化的時候也會使用移動構造函 數 在有臨時物件產生的情況下 這樣效率會高一些,如避免深度拷貝之類的操作 一旦初始化之後,在 進行 運算將...

OC中靜態構造和動態構造的區別

student.h import inte ce student nsobject property nonatomic,retain nsstring name property nonatomic,assign int age endstudent.m import student.h impl...