package packege1;
import javacard.framework.*;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.APDU;
import javacard.framework.Util;
/**
* 003E218080807F1E
* 1C3E6E40C0BE6101
* 224042049C9E6D00
*
*/
public class Lifegame extends Applet {
/*public static void install(byte[l b,short bOfset,byte bLength)throws ISOException
由JCRE调用,用于创建一个 Applet对象实例.
在方法执行过程中,首先将创建 Applet所需对象;
然后进行初始化操作,为数据赋初值;//
最后用 register方法将 Applet注册到ava智能卡平台中.
只有成功执行了 register方法,install才算执行成功.
若在install方法中没有调用 register方法或 register方法执行错误,则该 Applet安装失败.
public static void install(byte[] b, short bOffset, byte bLength) {
// GP-compliant JavaCard applet registration
new Lifegame().register(b, (short) (bOffset + 1), b[bOffset]);
}*/
//final static在该类所有对象里都是常量。
final static byte initialize =(byte)0x31;
final static byte evolve =(byte)0x32;
final static byte name =(byte)0x33;
final static byte stu_id =(byte)0x34;
final static byte[] NAME = {(byte)0xC0,(byte)0xEE,(byte)0xD3,(byte)0xF1,(byte)0xBC,(byte)0xA7};//
final static byte[] STU_ID = {'2','0','1','7','2','1','1','0','8','7'};
//名字C0 EE D3 F1 BC A7
//学号32 30 31 37 32 31 31 30 38 37
//行:row 2、列:column
byte row,col;
byte data_len ;
byte[] chessboard;// ={(byte)0x00,(byte)0x00,(byte)0xD3,(byte)0xF1,(byte)0xBC,(byte)0xA7,(byte)0xA7,(byte)0xA7};;
final static short MAX_BALANCE=0x7530 ;
final static short MAX_TRANSACTION_AMOUNT=0x1388;
//************************
final static byte PIN_TRY_LIMIT=(byte)0x03;
final static byte MAX_PIN_SIZE=(byte)0x08;
final static short SW_VERIFICATION_FAILED=0X6300;//密码错误
final static short SW_VERIFICATION_REQUIRED=0X6301;//交易前要求认证
short Balance=0;//余额//最大余额
//short 两字节
//下面的Lifegame函数为 Applet的构造函数,由 Install方法调用
//它负责 Applet对象实例的创建及初始化。
//虽然在任何时候都可以创建对象和数组,
//但推荐在 Applet构造函数中创建所有对象和数组,这样可以保证 Applet不会存在存储泄漏。
private Lifegame(byte[] b,short bOffset,byte bLength)
{
//∥取 install方法输入参数长度
byte iLen = b[bOffset]; //AID长度
bOffset=(short)(bOffset+iLen+1);
byte cLen=b[bOffset]; //info length
bOffset=(short)(bOffset+cLen+1);
byte aLen=b[bOffset]; // Applet data length
//pin=new OwnerPIN(PIN_TRY_LIMIT, MAX_PIN_SIZE);
//这是填的para,不需要pin.update(b,(short)(bOffset+1),aLen);
//register方法负责将 Applet实例注册到JCRE中,并为之分配相应的AID,
//该AID和Applet一一对应,JCRE可以通过此AID选择对应的 Applet根据 Applet注册的AID不同
register();
}
//install
public static void install(byte[] b,short bOffset,byte bLength)
{
new Lifegame( b , bOffset , bLength );
}
public void process(APDU apdu) {
// Good practice: Return 9000 on SELECT
//Applet在被选中之前,一直处在挂起状态,当JCRE收到一个 SELECT命令,
//且该SELECT命令的数据段和某个 Applet的实例化AID相一致时,该应用将被选中,JCRE将会调用 Applet的 select方法.
//当JCRE调用 Applet select后,
//由终端发送的命令将会交由 Applet process法解释执行。
//其中也包含选择应用时所发送的 SELECT命令,因此为了将 SELECT命令同其他命令区分开,
//提供了一个方法 Applet。selecting Applet0.若当前应用已被选择,则该方法返回true,否则返回 false,
if (selectingApplet()) {
return;
}
//通常情况下,process()方法将会首先检査输入命令结构是否正确,
//然后根据INS进入不同的处理流程,
//最后返回执行结果给终端。
//APDU对象负责传递终端发送的APDU命令。
//通过 APDU.getBuffer()命令,即可以得到APDU命令数组(APDU对象的通信缓冲区)
byte[] apdubuf = apdu.getBuffer();
switch (apdubuf[ISO7816.OFFSET_INS]) {
case (byte) initialize:
Initialize(apdu);
break;
case (byte) evolve:
Evolve(apdu);
break;
case (byte) name:
Name(apdu);
break;
case (byte) stu_id:
Stu_id(apdu);
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
/**********************************************************
**************演进****************************************
*
* 003E218080807F1E
* 1C3E6E40C0BE6101
* 224042049C9E6D00
*0060000610806000
*0000000000604000
***********************************************************/
void Evolve(APDU apdu)
{
byte[] buf = apdu.getBuffer();
byte x=0,y=0;
byte temp = 0;
for(y=0;y<row;y++)
{
for(x=0;x<col;x++)
{
run(x,y); //检查本格周围
}
}
if((x==(byte)0x08)&&(y==(byte)0x08))
{
for(y=0;y<row;y++)
{
buf[y] = 0;
for(x=0;x<col;x++)
{
chessboard[(byte)((x)+(y)*col)] = (byte)( chessboard[(byte)((x)+(y)*col)] >> 1 );
temp = (byte)(chessboard[(byte)((x)+(y)*col)] << (7 - x));
buf[y] = (byte)(temp | buf[y]);
}
}
}
apdu.setOutgoingAndSend((byte)0,(byte)data_len);
}
public void run(byte x, byte y)
{
byte activeSurroundingCell=0;//本界面棋盘储存在0000 0001这一位
if( (isVaildCell((byte)(x-1),(byte)(y-1))==1) &&((chessboard[(byte)((x-1)+(y-1)*col)]& (byte)0x01) ==1 ))
{activeSurroundingCell++;
}
if( (isVaildCell((byte)(x),(byte)(y-1)) ==1) && ((chessboard[(byte)((x)+(y-1)*col)] & (byte)0x01) ==1) )
activeSurroundingCell++;
if( (isVaildCell((byte)(x+1),(byte)(y-1))==1) &&((chessboard[(byte)((x+1)+(y-1)*col)] & (byte)0x01) !=0 ))
activeSurroundingCell++;
if( (isVaildCell((byte)(x-1),(byte)(y))==1) &&((chessboard[(byte)((x-1)+(y)*col)] & (byte)0x01) !=0 ))
activeSurroundingCell++;
if( (isVaildCell((byte)(x+1),(byte)(y))==1) &&((chessboard[(byte)((x+1)+(y)*col)] & (byte)0x01) !=0 ))
activeSurroundingCell++;
if( (isVaildCell((byte)(x-1),(byte)(y+1))==1) &&((chessboard[(byte)((x-1)+(y+1)*col)] & (byte)0x01)!=0 ))
activeSurroundingCell++;
if( (isVaildCell((byte)(x),(byte)(y+1))==1) &&((chessboard[(byte)((x)+(y+1)*col)] & (byte)0x01) !=0 ))
activeSurroundingCell++;
if( (isVaildCell((byte)(x+1),(byte)(y+1))==1) &&((chessboard[(byte)((x+1)+(y+1)*col)] & (byte)0x01) !=0 ))
activeSurroundingCell++;
switch (activeSurroundingCell) { //下一界面棋盘存在0000 0010这一位
case (byte) 2://保持原态
if( ( chessboard[(byte)((x)+(y)*col)]& (byte)0x01 ) !=0 )//本界面本格为一
{
chessboard[(byte)((x)+(y)*col)] = (byte)(chessboard[(byte)((x)+(y)*col)]|(byte)0x02);//下一界面本格或运算置1
}
else
{
chessboard[(byte)((x)+(y)*col)] = (byte)(chessboard[(byte)((x)+(y)*col)]&(byte)0xFD);//下一界面本格与运算置0
}
break;
case (byte) 3://置一
chessboard[(byte)((x)+(y)*col)] = (byte)(chessboard[(byte)((x)+(y)*col)]|(byte)0x02);//下一界面本格或运算置1
break;
default: //置零
chessboard[(byte)((x)+(y)*col)] = (byte)(chessboard[(byte)((x)+(y)*col)]&(byte)0xFD);//下一界面本格与运算置0
}
/*if((x==(byte)0x07)&&(y==(byte)0x07))
{
for(y=0;y
{
for(x=0;x
{
chessboard[(byte)((x)+(y)*col)] = (byte)( chessboard[(byte)((x)+(y)*col)] >> 1 );
buf[y] = chessboard[(byte)((x)+(y)*col)] << (7 - x);
}
}
}*/
/*
if(activeSurroundingCell==3)
{
nextGeneration[x][y]=CellStatus.Active;
}
else if(activeSurroundingCell==2)
{
nextGeneration[x][y]=currentGeneration[x][y];
}
else
{
nextGeneration[x][y]=CellStatus.Dead;
}*/
}
private byte isVaildCell(byte x,byte y)
{
if((x>=0)&&(x<row)&&(y>=0)&&(y<col))
{
return 1;
}
else
{
return 0;
}
}
/**********************************************************
**************初始化****************************************
* => 00 31 08 08 08 11 11 11 11 11 11 11 11
* <= 11 11 11 11 11 11 11 11 90 00
***********************************************************/
void Initialize(APDU apdu)
{
byte[] buf = apdu.getBuffer();
byte OFF1;
row = getUnsignedByte(buf[ISO7816.OFFSET_P1]);
col = getUnsignedByte(buf[ISO7816.OFFSET_P2]);
/*Java中数组的定义与使用方法bai:
1、数组的du定义
语法有两种:
type arrayName[];
type[] arrayName;
type 为Java中的任意zhi数据类型,包括基dao本类型和组合类型,arrayName为数组名,必须是一个合法的标识符,[ ] 指明该变量是一个数组类型变量。
例如:
int demo[];
int[] demo;
这两种形式没有区别,使用效果完全一样,读者可根据自己的编程习惯选择。
注意:Java在定义数组时并不为数组元素分配内存,因此[ ]中无需指定数组元素的个数,即数组长度。而且对于如上定义的一个数组是不能访问它的任何元素的,开发者必须要为它分配内存空间,这时要用到运算符new,其格式如下:
arrayName=new type[arraySize];
其中,arraySize 为数组的长度,type 为数组的类型。如:
demo=new int[3];//为一个整型数组分配3个int 型整数所占据的内存空间。
*/
chessboard = new byte[row*col];
data_len = (byte)apdu.setIncomingAndReceive();//接受到的data区的长度
OFF1 = ISO7816.OFFSET_CDATA;
//Util.arrayCopyNonAtomic( chessboard , (byte)0 , buf , OFF1 , data_len);
//存入棋盘
for(byte i=0;i<data_len;i++)
{
byte m = getUnsignedByte(buf[OFF1]);
//取高8位
for(byte j=0;j<8;j++)
{
chessboard[i*8+j] = getBit( m , (byte)(7-j) );//len没有改变。和len+3这种类比。只是把len的移位结果发送
}//取低8
//chessboard[i] = getUnsignedByte(buf[OFF1]);
OFF1 = (byte)(OFF1+1);
}
apdu.setOutgoingAndSend((byte)ISO7816.OFFSET_CDATA,(byte)data_len);
//apdu.setOutgoingAndSend((byte)0,(byte)data_len();
}
//b为传入的字节,i为第几位(范围0-7),如要获取bit0,则i=0
public byte getBit(byte b,byte i) {
byte bit = (byte)((b>>i) & 0x1);
return bit;
}
/**********************************************************
**************姓名****************************************
*=> 00 33 00 00 00
*<= C0 EE D3 F1 BC A7 90 00
***********************************************************/
void Name(APDU apdu)//返回名字的gb2312码
{
//short m;
byte[] buf = apdu.getBuffer();
//short p2=(short)getUnsignedByte(buf[ISO7816.OFFSET_P2]);
//m=(short)(buf[ISO7816.OFFSET_P1]*256+p2); //取p1,p2转化为一个数.short强制转换
/**
* 例子:计算报文长度,两字节报文长度(高位在前)
*/
/* public byte[] getByteMessageLen(int len) {
byte[] buf = new byte[2];
//取高8位
buf[0] = (byte) (len >> 8);//len没有改变。和len+3这种类比。只是把len的移位结果发送
//取低8
buf[1] = (byte) (len & 0xff);
return buf;
}
*/
//Balance=(short)(Balance-m);
//buf[0]=(byte)(Balance>>8);
//buf[1]=(byte)(Balance&0xff); //高两位
for(byte i=0;i<6;i++)
{
buf[i]= NAME[i];
}
apdu.setOutgoingAndSend((byte)0,(byte)6);
}
/**********************************************************
**************学号*****************************************
*=>
***********************************************************/
void Stu_id(APDU apdu)//返回名字的gb2312
{
byte[] buf = apdu.getBuffer();
for(byte i=0;i<10;i++)
{
buf[i]= STU_ID[i];
}
apdu.setOutgoingAndSend((byte)0,(byte)10);
}
public byte getUnsignedByte(byte data)
{ //将data字节型数据转换为0-255(0xEF即BYTE)
return(byte)(data&0x0FF); //部分编译器会把最高位当做符号位,因此写成0x0FF
}
}
本文来源:https://www.2haoxitong.net/k/doc/cfbf0f12fc4733687e21af45b307e87101f6f8af.html
文档为doc格式