如何获取JavaCard剩余空间
0x01应用场景
获取JavaCard卡内剩余空间,一方面是在评估一张卡的时候需要用到,另一方面是在应用个人化或者运行时需要用到。
例如:应用提供商为了保证自己的应用在卡内运行期间能够不受空间影响,一般会在个人化(安装应用)的时候先分配好需要用到的空间,以免空间被后来应用占用,导致运行失败。
0x02空间类型
卡内剩余空间包括获取卡内的剩余永久存储器(E2P or Flash),还有获取易失性存储器空间(RAM),这里的RAM分为两部分,一部分是在卡片复位时清零的内存CLEAR_ON_RESET,缩写为COR或者RTR(Clear_on_Reset Transient RAM);另一部分为应用在取消选择的时候清零的内存CLEAR_ON_DESELECT,缩写为COD或者DTR(Clear_on_Deselect Transient RAM)。本文将通过实例获取卡内的这三种存储器剩余空间。
0x03获取接口
对于获取JavaCard内可用空间,API提供了相应的接口JCSystem.getAvaliableMemory(byte memoryType) ,位于javacard.framework包下,如下所示,引用自JCAPI v2.2.2。
getAvailableMemorypublic static short getAvailableMemory(byte memoryType)
|
根据接口描述,如果可用字节数超过32767(0x3FFF),则只返回32767。那如何返回超过32767的空间,可参考本文后面的代码实例。
0x04代码实例
1.获取DTR剩余空间
/**
* 获取剩余MEMORY_TYPE_TRANSIENT_DESELECT空间
* @return
*/
public int getFreeDTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
allmemsize += memsize;
}
return allmemsize;
}
2.获取RTR剩余空间
/**
* 获取剩余的MEMORY_TYPE_TRANSIENT_RESET空间
* @return
*/
public int getFreeRTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
allmemsize += memsize;
}
return allmemsize;
}
3.获取E2P/Flash的剩余空间
/**
* 获取剩余的E2P/Flash空间,如果剩余空间大于0x3FFF,则此接口将创建数组,然后再获取新的剩余空间,
* 数组对象头将占用几个字节(根据对象存储结构不一样,可能占用字节数不同,一般数组头为7字节),因此存在误差。
* @return
*/
public int getFreePersistent(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
byte[] tmp=new byte[memsize]; //不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
allmemsize += memsize;
}
return allmemsize;
}
注意
1.获取剩余空间的应用自身的代码需要占用部分空间,本例中的应用代码主468字节,存储在卡内空间为 278 字节.
2.DTR与RTR可能使用同一块区域。
3.以上代码在使用converter转成cap文件时需要加上支持int类型的选项,如果卡片本身不支持int,则代码中相应的地方需要做调整,譬如说如果卡内相应存储器空间大于0x3FFF时,可以将每次取得的值存储在apdubuffer中,一起返回到卡外,然后再计算。
完整代码
package GetFreeSpacePkg; import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.Applet;
import javacard.framework.ISOException;
import javacard.framework.JCSystem; /**
* 获取卡内剩余空间,包括E2P/Flash与RAM.
* 对于E2P/Flash来说,如果卡内剩余空间超过0x3FFF,则此应用返回的数据会有较小的误差。
* 测试命令:
*
* 8000000000 //get DTR
* 8001000000 //get RTR
* 8002000000 //get E2P/Flash
*
* @author SCPlatform@outlook.com
*/
public class GetFreeSpaceApplet extends Applet {
public static void install(byte[] bArray, short bOffset, byte bLength) {
new GetFreeSpaceApplet().register(bArray, (short) (bOffset + 1),bArray[bOffset]);
} public void process(APDU apdu) {
if (selectingApplet()) {
return;
} byte[] buf = apdu.getBuffer();
int iFreeSpace=0;
switch (buf[ISO7816.OFFSET_INS]) {
case (byte) 0x00://DTR
iFreeSpace = getFreeDTR();
break;
case (byte) 0x01://RTR
iFreeSpace = getFreeRTR();
break;
case (byte) 0x02://persistent
iFreeSpace = getFreePersistent();
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
JCSystem.requestObjectDeletion();
buf[3]=(byte)(iFreeSpace);
buf[2]=(byte)(iFreeSpace>>8);
buf[1]=(byte)(iFreeSpace>>16);
buf[0]=(byte)(iFreeSpace>>24);
apdu.setOutgoingAndSend((short)0, (short)4);
}
/**
* 获取剩余MEMORY_TYPE_TRANSIENT_DESELECT空间
* @return
*/
public int getFreeDTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT);
allmemsize += memsize;
}
return allmemsize;
} /**
* 获取剩余的MEMORY_TYPE_TRANSIENT_RESET空间
* @return
*/
public int getFreeRTR(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
JCSystem.makeTransientByteArray(memsize,JCSystem.MEMORY_TYPE_TRANSIENT_RESET);//不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
allmemsize += memsize;
}
return allmemsize;
} /**
* 获取剩余的E2P/Flash空间,如果剩余空间大于0x3FFF,则此接口将创建数组,然后再获取新的剩余空间,
* 数组对象头将占用几个字节(根据对象存储结构不一样,可能占用字节数不同,一般数组头为7字节),因此存在误差。
* @return
*/
public int getFreePersistent(){
//首先取得剩余空间大小
short memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
int allmemsize = memsize;
//如果返回值为0x3FFF,则剩余空间大于此值,可继续取得剩余空间
while(memsize == (short)32767){
byte[] tmp=new byte[memsize]; //不存储返回的数组对象
memsize = JCSystem.getAvailableMemory(JCSystem.MEMORY_TYPE_PERSISTENT);
allmemsize += memsize;
}
return allmemsize;
}
}
0x05资料参考
1.Application Programming Interface Java Card™ Platform, Version 2.2.2
如何获取JavaCard剩余空间的更多相关文章
- Linux C++获取磁盘剩余空间和可用空间
完整源码 #include <sys/statfs.h> #include <string> #include <iostream> #include <li ...
- C# 获取磁盘剩余空间
drive.TotalFreeSpace单位为bit,根据需要除以1024 drive同时可以可以获取磁盘分区容量等 //单位MB public static long GetHardDiskSpac ...
- 两种方法,获取磁盘剩余空间--PYTHON
import ctypes import os import platform import sys def get_free_space_mb(folder): """ ...
- C# 获取电脑硬盘剩余空间
获取本地硬盘的所有剩余空间: 主要应用到System.IO类库的:Driveinfo.Directory,将model转换成json需要用到Newtonsoft.Json.JsonConvert.Se ...
- Android中StatFs获取系统/sdcard存储(剩余空间)大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- android计算每个目录剩余空间丶总空间以及SD卡剩余空间
ublic class MemorySpaceCheck { /** * 计算剩余空间 * @param path * @return */ public static String getAvail ...
- Android为TV端助力 计算每个目录剩余空间丶总空间以及SD卡剩余空间
ublic class MemorySpaceCheck { /** * 计算剩余空间 * @param path * @return */ public static String getAvail ...
- c# 读取所有磁盘的剩余空间
介绍: 有一个控制台命令是创建指定大小的空文件,因此我想制作一个一键填充剩余磁盘空间的坑人小程序. 想要填充剩余容量,就要先获取所有本地磁盘的剩余空间,这个程序就是用来做这个的. 项目类型为c#控制台 ...
- SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)
需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...
随机推荐
- 【洛谷2051】[AHOI2009] 中国象棋(烦人的动态规划)
点此看题面 大致题意: 让你在一张\(N*M\)的棋盘上摆放炮,使其无法互相攻击,问有多少种摆法. 辟谣 听某大佬说这是一道状压\(DP\)题,于是兴冲冲地去做,看完数据范围彻底懵了:\(N≤100\ ...
- cout对象一些常用方法的总结
cout.precision(n); 这个方法的功能是,设置精度为n,返还值是上一次的设置精度. #include <iostream> using namespace std; int ...
- PHP implode() 函数
转自:http://www.w3school.com.cn/php/func_string_implode.asp 语法 implode(separator,array) 参数 描述 separato ...
- iOS 反射函数: performSelector, NSInvocation, objc_msgSend
当我们有方法名和参数列表,想要动态地给对象发送消息,可用通过反射函数机制来实现,有两种常用的做法: 一.performSelector - (id)performSelector:(SEL)aSele ...
- GPT分区表的备份与恢复
GPT分区表的备份与恢复 keenshoes 2016-01-13 21:02:25 关键词: GPT, Partition, MBR,APPLE, GUID, Protective MBR 对于现 ...
- cookie 和 localStorage 、sessionStorage、 session不同
1. cookie:存储大小4k 有时间限制,会跟在ajax的请求头上 2. localStorage: 存储大小5M 没有时间限制 3. sessionStorage: 临时会话存储 当浏览器关闭的 ...
- 用JavaScript实现CheckBox的全选取消反选,及遮罩层中添加内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Java - 静态方法不具有多态性
class A1 { public static void f() { System.out.println("A1.f()"); }}class A2 extends A1 { ...
- LigerUI 快速开发UI框架 链接
LigerUI 快速开发UI框架 http://www.ligerui.com/ jQuery ligerUI 中文官方网站 http://www.ligerui.com/demo.html
- java util - Unicode转换工具
测试代码 package cn.java.codec.unicode; public class Test { public static void main(String[] args) throw ...