如何获取JavaCard剩余空间
0x01應(yīng)用場景
獲取JavaCard卡內(nèi)剩余空間,一方面是在評估一張卡的時候需要用到,另一方面是在應(yīng)用個人化或者運(yùn)行時需要用到。
例如:應(yīng)用提供商為了保證自己的應(yīng)用在卡內(nèi)運(yùn)行期間能夠不受空間影響,一般會在個人化(安裝應(yīng)用)的時候先分配好需要用到的空間,以免空間被后來應(yīng)用占用,導(dǎo)致運(yùn)行失敗。
0x02空間類型
卡內(nèi)剩余空間包括獲取卡內(nèi)的剩余永久存儲器(E2P or Flash),還有獲取易失性存儲器空間(RAM),這里的RAM分為兩部分,一部分是在卡片復(fù)位時清零的內(nèi)存CLEAR_ON_RESET,縮寫為COR或者RTR(Clear_on_Reset Transient RAM);另一部分為應(yīng)用在取消選擇的時候清零的內(nèi)存CLEAR_ON_DESELECT,縮寫為COD或者DTR(Clear_on_Deselect Transient RAM)。本文將通過實(shí)例獲取卡內(nèi)的這三種存儲器剩余空間。
0x03獲取接口
對于獲取JavaCard內(nèi)可用空間,API提供了相應(yīng)的接口JCSystem.getAvaliableMemory(byte memoryType) ,位于javacard.framework包下,如下所示,引用自JCAPI v2.2.2。?
? getAvailableMemorypublic static short getAvailableMemory(byte?memoryType)throws SystemExceptionNotes:
?
|
??根據(jù)接口描述,如果可用字節(jié)數(shù)超過32767(0x3FFF),則只返回32767。那如何返回超過32767的空間,可參考本文后面的代碼實(shí)例。
0x04代碼實(shí)例
1.獲取DTR剩余空間
1 /** 2 * 獲取剩余MEMORY_TYPE_TRANSIENT_DESELECT空間 3 * @return 4 */ 5 public int getFreeDTR(){ 6 //首先取得剩余空間大小 7 short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT); 8 int allmemsize = memsize; 9 //如果返回值為0x3FFF,則剩余空間大于此值,可繼續(xù)取得剩余空間 10 while(memsize == (short)32767){ 11 JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存儲返回的數(shù)組對象 12 memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT); 13 allmemsize += memsize; 14 } 15 return allmemsize; 16 }?2.獲取RTR剩余空間
1 /** 2 * 獲取剩余的MEMORY_TYPE_TRANSIENT_RESET空間 3 * @return 4 */ 5 public int getFreeRTR(){ 6 //首先取得剩余空間大小 7 short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 8 int allmemsize = memsize; 9 //如果返回值為0x3FFF,則剩余空間大于此值,可繼續(xù)取得剩余空間 10 while(memsize == (short)32767){ 11 JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存儲返回的數(shù)組對象 12 memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 13 allmemsize += memsize; 14 } 15 return allmemsize; 16 }?3.獲取E2P/Flash的剩余空間
1 /** 2 * 獲取剩余的E2P/Flash空間,如果剩余空間大于0x3FFF,則此接口將創(chuàng)建數(shù)組,然后再獲取新的剩余空間, 3 * 數(shù)組對象頭將占用幾個字節(jié)(根據(jù)對象存儲結(jié)構(gòu)不一樣,可能占用字節(jié)數(shù)不同,一般數(shù)組頭為7字節(jié)),因此存在誤差。 4 * @return 5 */ 6 public int getFreePersistent(){ 7 //首先取得剩余空間大小 8 short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT); 9 int allmemsize = memsize; 10 //如果返回值為0x3FFF,則剩余空間大于此值,可繼續(xù)取得剩余空間 11 while(memsize == (short)32767){ 12 byte[] tmp=new byte[memsize]; //不存儲返回的數(shù)組對象 13 memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT); 14 allmemsize += memsize; 15 } 16 return allmemsize; 17 }?注意
1.獲取剩余空間的應(yīng)用自身的代碼需要占用部分空間,本例中的應(yīng)用代碼主468字節(jié),存儲在卡內(nèi)空間為 278 字節(jié).
2.DTR與RTR可能使用同一塊區(qū)域。
3.以上代碼在使用converter轉(zhuǎn)成cap文件時需要加上支持int類型的選項,如果卡片本身不支持int,則代碼中相應(yīng)的地方需要做調(diào)整,譬如說如果卡內(nèi)相應(yīng)存儲器空間大于0x3FFF時,可以將每次取得的值存儲在apdubuffer中,一起返回到卡外,然后再計算。?
完整代碼
1 package GetFreeSpacePkg; 2 3 import javacard.framework.APDU; 4 import javacard.framework.ISO7816; 5 import javacard.framework.Applet; 6 import javacard.framework.ISOException; 7 import javacard.framework.JCSystem; 8 9 /** 10 * 獲取卡內(nèi)剩余空間,包括E2P/Flash與RAM. 11 * 對于E2P/Flash來說,如果卡內(nèi)剩余空間超過0x3FFF,則此應(yīng)用返回的數(shù)據(jù)會有較小的誤差。 12 * 測試命令: 13 * 14 * 8000000000 //get DTR 15 * 8001000000 //get RTR 16 * 8002000000 //get E2P/Flash 17 * 18 * @author SCPlatform@outlook.com 19 */ 20 public class GetFreeSpaceApplet extends Applet { 21 public static void install(byte[] bArray, short bOffset, byte bLength) { 22 new GetFreeSpaceApplet().register(bArray, (short) (bOffset + 1),bArray[bOffset]); 23 } 24 25 public void process(APDU apdu) { 26 if (selectingApplet()) { 27 return; 28 } 29 30 byte[] buf = apdu.getBuffer(); 31 int iFreeSpace=0; 32 switch (buf[ISO7816.OFFSET_INS]) { 33 case (byte) 0x00://DTR 34 iFreeSpace = getFreeDTR(); 35 break; 36 case (byte) 0x01://RTR 37 iFreeSpace = getFreeRTR(); 38 break; 39 case (byte) 0x02://persistent 40 iFreeSpace = getFreePersistent(); 41 break; 42 default: 43 ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); 44 } 45 JCSystem.requestObjectDeletion(); 46 buf[3]=(byte)(iFreeSpace); 47 buf[2]=(byte)(iFreeSpace>>8); 48 buf[1]=(byte)(iFreeSpace>>16); 49 buf[0]=(byte)(iFreeSpace>>24); 50 apdu.setOutgoingAndSend((short)0, (short)4); 51 } 52 /** 53 * 獲取剩余MEMORY_TYPE_TRANSIENT_DESELECT空間 54 * @return 55 */ 56 public int getFreeDTR(){ 57 //首先取得剩余空間大小 58 short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT); 59 int allmemsize = memsize; 60 //如果返回值為0x3FFF,則剩余空間大于此值,可繼續(xù)取得剩余空間 61 while(memsize == (short)32767){ 62 JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存儲返回的數(shù)組對象 63 memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT); 64 allmemsize += memsize; 65 } 66 return allmemsize; 67 } 68 69 /** 70 * 獲取剩余的MEMORY_TYPE_TRANSIENT_RESET空間 71 * @return 72 */ 73 public int getFreeRTR(){ 74 //首先取得剩余空間大小 75 short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 76 int allmemsize = memsize; 77 //如果返回值為0x3FFF,則剩余空間大于此值,可繼續(xù)取得剩余空間 78 while(memsize == (short)32767){ 79 JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存儲返回的數(shù)組對象 80 memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 81 allmemsize += memsize; 82 } 83 return allmemsize; 84 } 85 86 /** 87 * 獲取剩余的E2P/Flash空間,如果剩余空間大于0x3FFF,則此接口將創(chuàng)建數(shù)組,然后再獲取新的剩余空間, 88 * 數(shù)組對象頭將占用幾個字節(jié)(根據(jù)對象存儲結(jié)構(gòu)不一樣,可能占用字節(jié)數(shù)不同,一般數(shù)組頭為7字節(jié)),因此存在誤差。 89 * @return 90 */ 91 public int getFreePersistent(){ 92 //首先取得剩余空間大小 93 short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT); 94 int allmemsize = memsize; 95 //如果返回值為0x3FFF,則剩余空間大于此值,可繼續(xù)取得剩余空間 96 while(memsize == (short)32767){ 97 byte[] tmp=new byte[memsize]; //不存儲返回的數(shù)組對象 98 memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT); 99 allmemsize += memsize; 100 } 101 return allmemsize; 102 } 103 }?0x05資料參考
1.Application Programming Interface Java Card? Platform, Version 2.2.2
轉(zhuǎn)載于:https://www.cnblogs.com/SCPlatform/archive/2012/01/12/5125200.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的如何获取JavaCard剩余空间的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NSDateFormatter设定日期格
- 下一篇: 千万青年学子,双击电子版微积分