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...