聲明:本資料僅從技術(shù)的角度全面探討IC卡、IC電話卡及其安全性,由此引發(fā)的各種爭議或個(gè)人、集體利用本資料做任何不正當(dāng)用途本人概不負(fù)責(zé)。 目錄 Ⅰ)第一類卡(德國、西班牙、中國、香港、澳門等) Ⅰ-1)介紹: Ⅰ-2)引腳: Ⅰ-3)主要特性: Ⅰ-4)時(shí)序圖: Ⅰ-5)內(nèi)存數(shù)據(jù): Ⅱ)第二類卡(法國、墨西哥、捷克、瑞典、愛爾蘭等) Ⅱ-1)介紹: Ⅱ-2)引腳: Ⅱ-3)主要特性: Ⅱ-4)時(shí)序圖: Ⅱ-5)內(nèi)存數(shù)據(jù): Ⅱ-6)電氣參數(shù): Ⅰ) 第一類卡 Ⅰ-1)介紹 自從80年代中期出現(xiàn)IC電話卡后,基本已取代了原來流行的電話磁卡,磁卡存在存在嚴(yán)重的安全問題,已逐步淘汰。 即使IC電話卡,也不能算很安全,卡內(nèi)所有數(shù)據(jù)只要有簡單的讀寫裝置并按時(shí)序操作都能讀取,事實(shí)上電話卡和信用卡一樣內(nèi)部沒有什么秘密信息,僅僅是帶串行輸出的128位EPROM而已(對二類卡是256位PROM),不要以為弄懂了它是怎么工作你就有辦法重新對卡內(nèi)數(shù)據(jù)重新填充,其開始的64位是帶寫保護(hù)的,在出廠時(shí)其熔絲位已被編程,你已無法對其更改,其后的40位計(jì)數(shù)單元受內(nèi)部邏輯控制在寫時(shí)只能減少不能增加直至到0為止,因此你想用一般的IC電話卡打免費(fèi)電話是不可能的,除非你能用單片機(jī)仿真它(如果你能讀懂本文介紹的所有內(nèi)容)。IC電話卡是一種一次性使用的計(jì)數(shù)卡,以一次性的計(jì)數(shù)方式,從寫滿的計(jì)數(shù)器中減“1”,直至存儲單元減為空為止。 卡片每次消費(fèi)計(jì)數(shù)的“單位價(jià)值”根據(jù)各種應(yīng)用系統(tǒng)的實(shí)際需要而定。例如:對于中國IC電話卡,如30元卡對應(yīng)內(nèi)部計(jì)數(shù)值為300,每單位值對應(yīng)0.1元,IC 卡電話機(jī)每分鐘產(chǎn)生一次扣費(fèi)信號,扣費(fèi)值由當(dāng)?shù)豂C電話管理系統(tǒng)設(shè)定,一般是價(jià)值0.5元或1元,卡片被計(jì)數(shù)5次和10次。對于其它國家屬于第一類IC電話卡而言也是如此,只是內(nèi)部初始計(jì)數(shù)值不同,每次扣除額度不一樣罷了。其他對于公用加油卡,IC卡計(jì)費(fèi)加油機(jī)每一公升(或一加侖)產(chǎn)生一次扣費(fèi)操作,卡片被操作一次扣2.5元等等,均屬于等同原理。事實(shí)上,這類卡內(nèi)部為128位(16字節(jié)) NMOS存儲器,按如下規(guī)律分布: 64 位 EPPOM(8字節(jié)) 寫保護(hù)區(qū)(芯片數(shù)據(jù)代碼區(qū)、發(fā)行數(shù)據(jù)代碼區(qū)) 40 位 EEPROM(5字節(jié)) 24 位 為全“1”(3字節(jié)) 共16字節(jié)數(shù)據(jù)。 Ⅰ-2)引腳: -------------+------------- | 1 | 5 | 引 腳: | | | ------- +-------/ | /-------+ | 2 +----+ + 6 | 1 : Vcc = 5V 5 : Gnd | | | | 2 : Reset 6 : NC +--------| |--------+ 3 : Clock 7 : I/O | 3 | | 7 | 4 : NC 8 : NC | +----+----+ | +-------/ | /-------+ Vcc:電源 Gnd:地腳 Reset:復(fù)位 | 4 | 8 | | | | Clock:時(shí)鐘 I/O:數(shù)據(jù) NC: 空腳 -------------+------------- 因有三個(gè)腳為空腳,目前一般有采用8腳和6腳封裝的,6腳封裝的無最下一排兩個(gè)空腳 Ⅰ-3)主要特性: -采用單一5V電源供電 -遵循ISO/IEC7816-3同步協(xié)議進(jìn)行雙向數(shù)據(jù)傳輸 -低功耗 -NMOS技術(shù) -高可靠性,抗靜電干擾能力>4KV Ⅰ-4)時(shí)序圖 復(fù)位: 為使地址計(jì)數(shù)器復(fù)位到0,先讓Reset端變高。緊跟著一個(gè)Clock脈沖(從低到高再降到0),Reset重新變低,把Clock脈沖包住。隨著Reset端變低,地址0單元的數(shù)據(jù)從I/O上輸出。對應(yīng) Clock端的每個(gè)脈沖,其上升沿使地址計(jì)數(shù)器增加。其下降沿使被選通地址單元的數(shù)據(jù)從I/O上輸出。地址計(jì)數(shù)器增加到127后返回到0。 __________________ _____| |_____________________________________________ Reset : : : _____ : _____ _____ _____ _____ _____:_______| |____:_| |_____| |_____| |_____| |_ Clk : : : : : : : : : : : _____:_______:__________:_:_____:_____:_____:_____:_____:_____:_____:_ _____:___n___|_____0____:_|_____1_____|_____2_____|_____3_____|___4_:_ (Address) : : : : : : _____: :_______:___________:___________:___________:_ _____XXXXXXXXXXXXXXXXXXXX_______|___________|___________|___________|_ Data Bit n Bit 0 Bit 1 Bit2 Bit3 寫位: 在Reset和Clk端均為低的情況下,如果某地址單元允許寫操作(64-103位,且該位必需為1),則Reset端上的一個(gè)脈沖(即從低到高再回低)將允許芯片進(jìn)行位寫操作。在緊跟著的時(shí)鐘脈沖期間執(zhí)行寫操作,調(diào)整寫操作維持時(shí)間至少10ms,在這個(gè)CLK脈沖期間,地址計(jì)數(shù)器不會增加,在CLK寫脈沖下降沿,數(shù)據(jù)0從I/O端輸出。從Reset脈沖的上升沿到CLK寫脈沖的下降沿期間,I/O端的數(shù)據(jù)是無效的。在下一個(gè)才CLK脈沖,且Reset為低時(shí),地址計(jì)數(shù)器又增1,并在下降沿時(shí),把選通的地址單元的數(shù)據(jù)送到I/O端。 _____ _____ _____________| |______________________________| |_______________ Reset : : ___ : _____ ___ : _____ ____| |____:__________| |_________| |_____:__________| |____ Clk : : : : : : : : : ____:________:__________:_____:_________:___:_____:__________:_____:_____ n | n+1 | n+2 | : n+3 | : (Address) ----’--------:----------’-----:---------’---:-----:----------’-----:----- : : : : : : : _________ _: : : ____________: ___: : : _________XXX_XXXXXXXXXXXXXXXXXXX____________ XX___XXXXXXXXXXXXXXXXXXXXXXX I/O n n+1 : : n+1 n+2 : : : : : : write write 借位寫后的字節(jié)擦除: 對位地址72-103的字節(jié)單元來說,只要在每個(gè)字節(jié)的前面一位進(jìn)行一次正常的寫操作,就可以對此字節(jié)后一字節(jié)進(jìn)行字節(jié)擦除操作。也就是說,每向高一字節(jié)進(jìn)行借位(即寫一位0),緊接著的擦除時(shí)序可以對后一字節(jié)按字節(jié)擦除(即整個(gè)字節(jié)寫1)。被擦除的字節(jié)總是比借位寫的字節(jié)低一字節(jié)。從以下時(shí)序圖可以看出,首先,完成一個(gè)“位寫”操作,在CLK的寫脈沖結(jié)束后,在CLK為低電平時(shí),在發(fā)一個(gè)Reset脈沖即啟動(dòng)字節(jié)擦除操作。在第二個(gè)CLK脈沖完成字節(jié)擦除,脈沖維持時(shí)間整定為擦除周期時(shí)間(至少1ms)。芯片邏輯控制電路驗(yàn)證了借位寫確已完成從“1”寫“0”后,才擦除其低位字節(jié)。從Reset的上升沿到擦除操作的CLK脈沖的下降沿,I/O腳上的數(shù)據(jù)無效。地址計(jì)數(shù)器仍然停留在借位寫的地址上。 _____ _____ ______| |____________________| |_________________________________ Rst : : : _______ : _______ ___ ______:___________| |______:_____________| |______| |______ Clk : : : : : : : : : : : : : : : : <------------------------- address n ------------------------>:<--- n+1 ------ : : : : : : : : : : : : : : ______: : :______: : :__________: _____ ______XXXXXXXXXXXXXXXXXXXXX______XXXXXXXXXXXXXXXXXXXXXXX__________XX_____ I/O : : n : : n n+1 : : : : Write Erase 計(jì)數(shù)方法: 在67-103地址單元中分為5個(gè)不可重置8單元計(jì)數(shù)器,芯片初始化時(shí),72-103地址單元所對應(yīng)的4個(gè)較低的8單元計(jì)數(shù)器中可以放0到8個(gè)“1”而67-71地址單元所對應(yīng)的第5個(gè)計(jì)數(shù)器可以放0到5個(gè)“1”。所謂計(jì)數(shù)一次,就是將一個(gè)單元從“1”寫成“0”。一個(gè)計(jì)數(shù)器中8位全為“0”后,要計(jì)數(shù),需借位操作,即將高位計(jì)數(shù)器的一位從“1”寫成“0”而相應(yīng)其低位計(jì)數(shù)器整個(gè)字節(jié)從“0”擦除成“1”??梢?個(gè)8單元計(jì)數(shù)器如此逐一遞減,其最大計(jì)數(shù)為8的4次方=4096。第5個(gè)計(jì)數(shù)器中5個(gè)單元因處在最高位只能被寫“0”無法擦成“1”。因此只能計(jì)數(shù)5次。故芯片總計(jì)數(shù)為5X4096=20480。當(dāng)全部計(jì)數(shù)單元(地址67-103)都被寫成“0”時(shí),卡片就用完了,不過,芯片出廠初始化時(shí),初置的計(jì)數(shù)值由國家不同和卡片面值不同而不同,如100元卡初置計(jì)數(shù)值為1000。 舉例: 100元(1000計(jì)數(shù)單元預(yù)置初始值). -------- Byte9 Byte10 Byte11 Byte12 Byte13 -------------------------------------------------------------- 000000 - 00000001 - 01111111 - 00011111 - 00000000 -------------------------------------------------------------- (3)octal (6)octal (7)octal (1)octal (2)octal -------------------------------------------------------------- Value = 0*8^4 + 1*8^3 + 7*8^2 + 5*8^1 + 0*8^ -------------------------------------------------------------- 總值 = 1000 Units Ⅰ-5)內(nèi)存數(shù)據(jù): 字節(jié) 位 二進(jìn)制 十六進(jìn)制 +-----------+-----+ 1 1 --> 8 | | | +-----------+-----+ 2 9 --> 16 | 0010 1111 | $2F | ---> 德國 | 0011 0111 | $37 | ---> 西班牙 | 0011 1011 | $3B | ---> 希臘 +-----------+-----+ 3 17 --> 24 | | | 4 25 --> 32 | | | ---> 出廠編號(寫保護(hù)) 5 33 --> 40 | | | 6 41 --> 48 | | | 7 49 --> 56 | | | 8 57 --> 64 | | | +-----------+-----+ 9 65 --> 72 | | | ---> c4096 ) 10 73 --> 80 | | | ---> c512 ) 11 81 --> 88 | | | ---> c64 ) 5個(gè)8進(jìn)制計(jì)數(shù)區(qū) 12 89 --> 96 | | | ---> c8 ) 13 97 --> 104 | | | ---> c0 ) +-----------+-----+ 14 105 --> 112 | 1111 1111 | $FF | 15 113 --> 120 | 1111 1111 | $FF | ---> 所有位都為"1" 16 120 --> 128 | 1111 1111 | $FF | +-----------+-----+ 如需某一國家卡內(nèi)數(shù)據(jù)詳細(xì)數(shù)據(jù)請與作者聯(lián)系。 Ⅱ)第二類卡 Ⅱ-1)介紹: 二類卡與一類卡的區(qū)別在于,二類卡為256位PROM卡,在計(jì)數(shù)方式上有區(qū)別,一類卡5個(gè)計(jì)數(shù)單元組成5位8進(jìn)制遞減計(jì)數(shù)單元,有較大的計(jì)數(shù)范圍,而二類卡的計(jì)數(shù)單元每一位只能計(jì)數(shù)一次,在寫為“1”后該位即無效,另外在引腳設(shè)置、操作時(shí)序上也不相同。 Ⅱ-2)引腳: -------------+------------- | 1 | 5 | | | | +-------/ | /-------+ | 2 +----+ + 6 | | | | | +--------| |--------+ | 3 | | 7 | | +----+----+ | +-------/ | /-------+ | 4 | 8 | | | | -------------+------------- 1 : Vcc = 5V 5 : Gnd 2 : R/W 6 : Vpp = 21V 3 : Clock 7 : I/O 4 : Reset 8 : Fuse 1:電源腳 2:讀寫控制 3:時(shí)鐘 4:復(fù)位 5:接地 6:熔絲電壓 7:輸入輸出 8:熔絲控制
Ⅱ-3)主要特性: -同步傳輸協(xié)議 -N-MOS技術(shù) -256X1位 -96位帶寫保護(hù) -低功率85mW -21V熔絲電壓 -響應(yīng)時(shí)間:500ns -10年以上數(shù)據(jù)保持 Ⅱ-4)時(shí)序圖: +21V _____________ +5V ____________________________________| |_________________ Vpp : : +5V ___________________:_____________:_________________ Reset 0V ________________| : : : : : +5V ____ : ____ : ______:______ 0V ___| |_______:_____| |________:______| : |__________ Clock : : : : : : : : : +5V : : : : : :______:______: : _ 0V ___:____:_______:_____:____:________| : |______:__________ R/W : : : : : : : : : +5V : : :_____: :________: : : :__________ 0V XXXXXXXXXXXXXXXXX_____XXXXXX________XXXXXXXXXXXXXXXXXXXXXX__________ Out : : : : : :<-----><---->: : : : : : : :10 to 10 to : : : : : : :50 ms 50ms : 卡復(fù)位 Bit 1 Bit2 Bit 3 讀 讀 Bit2 寫為1 讀 -5)內(nèi)存數(shù)據(jù): 法國和摩洛哥等: 字節(jié) 位 進(jìn)制 十六進(jìn)制 +-----------+-----+ 1 1 --> 8 | | | +-----------+-----+ 2 9 --> 16 | 0000 0011 | $03 | ---> 法國卡 +-----------+-----+ 3 17 --> 24 | | | +-----------+-----+ 4 25 --> 32 | | | +-----------+-----+ 5 33 --> 40 | | | +-----------+-----+ 6 41 --> 48 | | | +-----------+-----+ 7 49 --> 56 | | | +-----------+-----+ 8 57 --> 64 | | | +-----------+-----+ 9 65 --> 72 | | | +-----------+-----+ 10 73 --> 80 | | | +-----------+-----+ 11 81 --> 88 | | | +-----------+-----+ 12 33 --> 40 | 0001 0011 | $13 | ---> 120 units card | 0000 0110 | $06 | ---> 50 units card | 0000 0101 | $05 | ---> 40 units card +-----------+-----+ 13-31 97 --> 248 | | | ---> 計(jì)數(shù)單元區(qū): 每消耗一單位,該位被寫 | | | 為“1”,一般開始10為為工廠作熔絲 | | | 測試寫為“1” | | | | | | | | | | | | +-----------+-----+ 32 249 --> 256 | 1111 1111 | $FF | ---> 空卡指示 +-----------+-----+ 其它國家: 字節(jié) 位 進(jìn)制 十六進(jìn)制 +-----------+-----+ 1 1 --> 8 | | | +-----------+-----+ 2 9 --> 16 | 1000 0011 | $83 | ---> 電話卡標(biāo)記 +-----------+-----+-----------+-----+ 3-4 17 --> 32 | 1000 0000 | $80 | 0001 0010 | $12 | ---> 10 元 卡 | | | 0010 0100 | $24 | ---> 22 元 卡 | | | 0010 0111 | $27 | ---> 25 元 卡 | | | 0011 0010 | $32 | ---> 30 元 卡 | | | 0101 0010 | $52 | ---> 50 元 卡 | | | 0110 0010 | $62 | ---> 60 元 卡 | | | 1000 0010 | $82 | ---> 80 元 卡 | 1000 0001 | $81 | 0000 0010 | $02 | ---> 100 元 卡 | | | 0010 0010 | $22 | ---> 120 元 卡 | | | 0101 0010 | $52 | ---> 150 元 卡 +-----------+-----+-----------+-----+ 5 33 --> 40 | | | ---> $00 for sweden. +-----------+-----+ 6 41 --> 48 | | | +-----------+-----+ 7 49 --> 56 | | | +-----------+-----+ 8 57 --> 64 | | | +-----------+-----+ 9 65 --> 72 | | | +-----------+-----+ 10 73 --> 80 | | | +-----------+-----+ 11 81 --> 88 | | | ---> $11 為瑞典 +-----------+-----+ 12 89 --> 96 | 0001 1110 | $1E | ---> 瑞典 | 0011 0000 | $30 | ---> 挪威 | 0011 0011 | $33 | ---> 安道爾 | 0011 1100 | $3C | ---> 愛爾蘭 | 0100 0111 | $47 | ---> 葡萄牙 | 0101 0101 | $55 | ---> 捷克 | 0101 1111 | $5F | ---> 加蓬 | 0110 0101 | $65 | ---> 芬蘭 +-----------+-----+ 13-31 97 --> 248 | | | ---> 計(jì)數(shù)單元區(qū): 每消耗一單位,該位被寫 | | | 為“1”,一般開始2為為工廠作熔絲 | | | 測試寫為“1” 。 | | | | | | | | | | | | +-----------+-----+ 32 249 --> 256 | 0000 0000 | $00 | +-----------+-----+ Ⅲ)電氣參數(shù): +--------+------+------+------+ | Symbol | Min | Max | Unit | +----------------------+--------+------+------+------+ | Supply voltage | Vcc | -0.3 | 6 | V | 電源電壓 +----------------------+--------+------+------+------+ | Input voltage | Vss | -0.3 | 6 | V | 輸入電壓 +----------------------+--------+------+------+------+ | Storage temperature | Tstg | -20 | +55 | | 儲存溫度 +----------------------+--------+------+------+------+ | Power dissipassion | Pd | - | 50 | mW | 功率 +----------------------+--------+------+------+------+ 直流參數(shù): +--------+-----+-----+-----+------+ | Symbol | Min.| Typ.| Max.| Unit | +---------------------------+--------+-----+-----+-----+------+ | Suplly current | Icc | - | - | 5 | mA | 電源電流 +---------------------------+--------+-----+-----+-----+------+ | Input Voltage (low) | Vl | 0 | - | 0.8 | V | 輸入電壓(低) +---------------------------+--------+-----+-----+-----+------+ | Input voltage (high) | Vh | 3.5 | - | Vcc | V | 輸入電壓(高) +---------------------------+--------+-----+-----+-----+------+ | Input current R | Ih | - | - | 100 | uA | 輸入電流(復(fù)位) +---------------------------+--------+-----+-----+-----+------+ | Input current Clk | Il | - | - | 100 | uA | 輸入電流(時(shí)鐘) +---------------------------+--------+-----+-----+-----+------+ | Output current (Low) | Iol | - | - | 10 | uA | 輸出電流(低電平) +---------------------------+--------+-----+-----+-----+------+ | Output current (High) | Ioh | - | - | 0.5 | mA | 輸出電流(高電平) +---------------------------+--------+-----+-----+-----+------+ 動(dòng)態(tài)參數(shù): +--------+------+------+------+ | Symbol | Min. | Max. | Unit | +----------------------+--------+------+------+------+ | Pulse duration | tr | 50 | - | us | | R address reset | | | | | 復(fù)位時(shí)復(fù)位脈沖持續(xù)時(shí)間 +----------------------+--------+------+------+------+ | Pulse duration | ts | 10 | - | us | | R write | | | | | 寫位時(shí)復(fù)位脈沖持續(xù)時(shí)間 +----------------------+--------+------+------+------+ | High level Clk | th | 8 | - | us | 時(shí)鐘高電位時(shí)間 +----------------------+--------+------+------+------+ | Low level Clk | tl | 12 | - | us | 時(shí)鐘低電位時(shí)間 +----------------------+--------+------+------+------+ | Write window | Twrite | 10 | - | ms | 寫位時(shí)間 +----------------------+--------+------+------+------+ | Erase window | Terase | 10 | - | ms | 擦除時(shí)間 +----------------------+--------+------+------+------+ | | tv1 | 5 | - | us | +----------------------+--------+------+------+------+ | | tv2 | 3.5 | - | us | +----------------------+--------+------+------+------+ | | tv3 | 3.5 | - | us | +----------------------+--------+------+------+------+ | | tv4 | 3.5 | - | us | +----------------------+--------+------+------+------+ | | tv5 | 3.5 | - | us | +----------------------+--------+------+------+------+ | | tv6 | 5 | - | us | +----------------------+--------+------+------+------+ | | tv7 | 5 | - | us | +----------------------+--------+------+------+------+ | | tv8 | 10 | - | us | +----------------------+--------+------+------+------+ Ⅳ)讀卡器電路圖: 簡易讀卡器電路圖(利用電腦打印口,可讀一類、二類卡) 外接5V (可選) 5V o------, | / T2 PNP d13 r7 10 0V o--, | / BC 177 |/ | _____ | | ,-------o/ o--*------. E C .--| >+-[_____]--------, __+__ | | | / / |/ | | ///// | __|__ Batery | / / | | - 22.5V | --------- | ....... | | | _____ | _____ | : | __+__ +--[_____]--*--[_____]--, | D2 : | ///// r6 150k r5 15k | | 4 o-------|---------------------------*------------------|-------------, | : | | r3 220k / C | | Ack : | | _____ |/ T1 - NPN | | 10 o------|--------. ’--[_____]-*---| BC107 | | : | | _____ | |/ | | : ,-, ,-, +--[_____]-’ / E | | : | |r2 | |r1 | r4 390k | | | : | |220 | |22k __+__ __+__ | | : |_| |_| ///// ///// | | : | |/ | | | | : *--| >+--|----------------*----------------------------------|--* : | |/ | | ,-----|-----------------------------, | | : | d1 | | | ,----------,----------, | | | : | | | *---|--* Fuse | Reset *--|---’ | | : | | | | |----------|----------| | | D0 : | | | ,-|---|--* I/O | Clk *--|---, | | 2 o-------|--------|----------’ | | |----------|----------| | | | : | | | ’---|--* Vpp | R/W *--|---|----’ | Busy : | | | |----------|----------| | | 11 o------|--------|--------------’ ,---|--* Gnd | 5V * | | | : | | | ’----------’-------|--’ | | D1 : | | __+__ Chip connector | | | 3 o-------|--------|--------, ///// | | | : | | ’------------------------------|------’ | Str : | |/ | | | | 1 o-------*--| >+--*----*----*----*----*-------------------’ | : d2|/ | |d3 |d4 |d5 |d6 |d7 | : -+- -+- -+- -+- -+- | : /_/ /_/ /_/ /_/ /_/ | D3 : | | | | | |/ | d8 | 5 o----------------*----|----|----|----|---| >+-------*-------------------’ : | | | | |/ | | : | | | | | D4 : | | | | |/ | d9 | 6 o---------------------*----|----|----|---| >+-------* : | | | |/ | | : | | | | D5 : | | | |/ | d10 | 7 o--------------------------*----|----|---| >+-------* : | | |/ | | : | | | D6 : | | |/ | d11 | 8 o-------------------------------*----|---| >+-------* : | |/ | | : | | D7 : | |/ | d12 | 9 o------------------------------------*---| >+-------’ : |/ | : : 25 o------. : | .......: | d1 to d13: 1N4148 __+__ ///// Ⅴ)讀卡程序: 下面程序?yàn)榕c簡易讀卡器相配套二類卡讀卡源程序(如需一類卡源程序或需C源程序或其可執(zhí)行程序請與作者聯(lián)系) USES crt,dos; CONST port_address=$378; { lpr1 chosen } TYPE string8=string[8]; string2=string[2]; VAR reg : registers; i,j : integer; Data : array[1..32] of byte; car : char; byte_number : integer; displaying : char; {-----------------------------------------------------------------------------} PROCEDURE Send(b:byte); BEGIN port[port_address]:=b; END; {-----------------------------------------------------------------------------} FUNCTION Get:byte; BEGIN get:=port[port_address+1]; END; {-----------------------------------------------------------------------------} { FUNCTION dec2hexa_one(decimal_value):hexa_character_representation; } { } { - convert a 4 bit long decimal number to hexadecimal. } {-----------------------------------------------------------------------------} FUNCTION dec2hexa_one(value:byte):char; BEGIN case value of 0..9 : dec2hexa_one:=chr(value+$30); 10..15 : dec2hexa_one:=chr(value+$37); END; END; {-----------------------------------------------------------------------------} { FUNCTION d2h(decimal_byte):string2; } { } { - convert a decimal byte to its hexadecimal representation. } {-----------------------------------------------------------------------------} FUNCTION d2h(value:byte):string2; VAR msbb,lsbb:byte; BEGIN msbb:=0; if ( value >= $80 ) then BEGIN msbb:=msbb+8; value:=value-$80; END; if ( value >= $40 ) then BEGIN msbb:=msbb+4; value:=value-$40; END; if ( value >= $20 ) then BEGIN msbb:=msbb+2; value:=value-$20; END; if ( value >= $10 ) then BEGIN msbb:=msbb+1; value:=value-$10; END; lsbb:=0; if ( value >= $08 ) then BEGIN lsbb:=lsbb+8; value:=value-$08; END; if ( value >= $04 ) then BEGIN lsbb:=lsbb+4; value:=value-$04; END; if ( value >= $02 ) then BEGIN lsbb:=lsbb+2; value:=value-$02; END; if ( value >= $01 ) then BEGIN lsbb:=lsbb+1; value:=value-$01; END; d2h := dec2hexa_one(msbb) + dec2hexa_one(lsbb); END; {-----------------------------------------------------------------------------} Function Binary( b : byte):string8; var weigth : byte; s : string8; BEGIN weigth:=$80; s:=’’; while (weigth > 0) do BEGIN if ((b and weigth) = weigth) then s:=s+’1’ else s:=s+’0’; weigth:=weigth div $02; END; Binary:=s; END; {-----------------------------------------------------------------------------} FUNCTION Units:byte; VAR u, i : integer; s : string8; BEGIN u:=0; i:=13; while (Data[i] = $FF) do BEGIN u:=u+8; i:=i+1; END; s:=Binary(Data[i]); while(s[1]=’1’) do BEGIN inc(u); s:=copy(s,2,length(s)); END; units:=u; END; {-----------------------------------------------------------------------------} function Units_2:LongInt; BEGIN Units_2:=4096*Data[9]+512*Data[10]+64*Data[11]+8*Data[12]+Data[13]; END; {-----------------------------------------------------------------------------} PROCEDURE Card_Type; BEGIN case Data[2] of $03: BEGIN write(’Telecard - France - ’); case Data[12] of $13: write(’120 Units - ’,units-130,’ Units left’); $06: write(’50 Units - ’,units-60,’ Units left’); $15: write(’40 Units - ’,units-40,’ Units left’); END; END; $2F:BEGIN write(’Telecard - Germany - ’, Units_2, ’ Units left’); END; $3B:BEGIN write(’Telecard - Greece - ’, Units_2, ’ Units left’); END; $83:BEGIN write(’Telecard’); case Data[12] of $1E: write(’ - Sweden’); $30: write(’ - Norway’); $33: write(’ - Andorra’); $3C: write(’ - Ireland’); $47: write(’ - Portugal’); $55: write(’ - Czech Republic’); $5F: write(’ - Gabon’); $65: write(’ - Finland’); END; if (Data[12] in [$30,$33,$3C,$47,$55,$65]) then BEGIN case ((Data[3] and $0F)*$100+Data[4]) of $012: write (’ - 10 Units - ’,units-12,’ Units left’); $024: write (’ - 22 Units - ’,units-24,’ Units left’); $027: write (’ - 25 Units - ’,units-27,’ Units left’); $032: write (’ - 30 Units - ’,units-32,’ Units left’); $052: write (’ - 50 Units - ’,units-52,’ Units left’); $067: write (’ - 65 Units - ’,units-62,’ Units left’); $070: write (’ - 70 Units - ’,units-70,’ Units left’); $102: write (’ - 100 Units - ’,units-102,’ Units left’); $152: write (’ - 150 Units - ’,units-152,’ Units left’); END; END; { write(’ - N?’,Data[5]*$100+Data[6]);} END; END; END; {-----------------------------------------------------------------------------} PROCEDURE waiting; BEGIN send($00); write(’Enter a card in the reader and press a key ...’); repeat until keypressed; gotoxy(1, wherey); clreol; END; {-----------------------------------------------------------------------------} PROCEDURE Full_Displaying; BEGIN writeln(’Memory dump:’); for i:=1 to 80 do write(’-’); for i:=1 to (byte_number div 6 + 1) do BEGIN for j:=1 to 6 do BEGIN if j+6*(i-1) <= byte_number then write(binary(Data[j+6*(i-1)]):9); END; gotoxy(60,wherey); for j:=1 to 6 do if j+6*(i-1) <= byte_number then write(d2h(Data[j+6*(i-1)]),’ ’); writeln; END; for i:=1 to 80 do write(’-’); Card_Type; writeln; END; {-----------------------------------------------------------------------------} PROCEDURE Short_Displaying; VAR j : integer; BEGIN for j:=1 to byte_number do BEGIN write(d2h(Data[j]),’ ’); END; writeln; END; {-----------------------------------------------------------------------------} PROCEDURE Reading; VAR i, j : integer; Value : byte; BEGIN send($FE); send($F8); for i:=1 to 32 do BEGIN Value:=0; for j:=1 to 8 do BEGIN Value:=Value*$02 + ((get and $08) div $08); send($FB); delay(1); send($F8); END; Data[i]:=Value; END; case displaying of ’F’:full_displaying; ’S’:short_displaying; END; END; {-----------------------------------------------------------------------------} PROCEDURE writting; VAR i,n:integer; car:char; BEGIN write(’Which bit do you want to set to "1" : ’); readln(n); waiting; car:=readkey; send($FA); send($F8); for i:=1 to n do BEGIN send($F9); if i=n then BEGIN send($FD); delay(20); send($FF); delay(20); END; send($FB); END; reading; END; {-----------------------------------------------------------------------------} PROCEDURE Saving; VAR filename : string; f : text; i : word; BEGIN write(’Enter the filename: ’); readln(filename); assign(f, filename); rewrite(f); for i:=1 to byte_number do write(f,d2h(Data[i]),’ ’); close(f); END; {-----------------------------------------------------------------------------} PROCEDURE initialize; VAR i : integer; BEGIN byte_number:=32; displaying:=’F’; clrscr; writeln(’ 1 - to dump a 256 bits card’); writeln(’ 2 - to dump a 128 bits card’); writeln(’ F - to display in full format’); window(41,1,80,25); writeln(’ S - to display in short format’); writeln(’ F2 - to save in a file’); writeln(’ Q - to exit the program’); window(1,4,80,25); for i:=1 to 80 do write(’=’); window(1,5,80,25); END; {=============================================================================} BEGIN initialize; repeat waiting; car:=upcase(readkey); case car of ’W’:writting; ’Q’:; ’1’:byte_number:=32; ’2’:byte_number:=16; ’F’,’S’:displaying:=car; #00: BEGIN car:=readkey; if car=#60 then saving; END; else reading; END; until car=’Q’; END.
|