解释一个 java 卡片 HelloWorld 小程序
Interpreting a java card HelloWorld applet
下面,你看到一个java卡程序,当它收到APDU命令时returns "Hello Word" =8000000000
(its source)
package helloWorldPackage;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
public class HelloWorldApplet extends Applet
{
private static final byte[] helloWorld = {(byte)'H',(byte)'e',(byte)'l',(byte)'l',(byte)'o',(byte)' ',(byte)'W',(byte)'o',(byte)'r',(byte)'l',(byte)'d',};
private static final byte HW_CLA = (byte)0x80;
private static final byte HW_INS = (byte)0x00;
public static void install(byte[] bArray, short bOffset, byte bLength)
{
new HelloWorldApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public void process(APDU apdu)
{
if (selectingApplet())
{
return;
}
byte[] buffer = apdu.getBuffer();
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS] & 0xFF);
if (CLA != HW_CLA)
{
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch ( INS )
{
case HW_INS:
getHelloWorld( apdu );
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void getHelloWorld( APDU apdu)
{
byte[] buffer = apdu.getBuffer();
short length = (short) helloWorld.length;
Util.arrayCopyNonAtomic(helloWorld, (short)0, buffer, (short)0, (short) length);
apdu.setOutgoingAndSend((short)0, length);
}
}
我明白了,但我不明白为什么程序员在行中使用&0XFF
:
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS] & 0xFF);
为什么他通常不使用下面这行?
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA]);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS]);
并且也在行中:
ew HelloWorldApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
+1
是什么意思?
虽然我们看不到作者的意图,但行:
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
100% 等同于:
byte CLA = buffer[ISO7816.OFFSET_CLA];
Java确实经常使用整数作为运算结果,并且由于Java卡通常不支持int
值,因此经常需要转换为byte
或 short
。我只能猜测 & 0xFF
和演员表的存在是因为过于热心地试图摆脱中间 int
值。让 Java 支持无符号字节也可能是一个糟糕的尝试。
register
方法需要实例 AID。该 AID 在全球平台 INSTALL for INSTALL
期间给出的用户参数范围内,但它前面有一个包含 AID 长度的字节(介于 5 和 15 之间,包括在内)。所以 + 1
是跳过那个长度字节——它又出现在 register
方法的最后一个参数中:bArray[bOffset]
.
下面,你看到一个java卡程序,当它收到APDU命令时returns "Hello Word" =8000000000
(its source)
package helloWorldPackage;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
public class HelloWorldApplet extends Applet
{
private static final byte[] helloWorld = {(byte)'H',(byte)'e',(byte)'l',(byte)'l',(byte)'o',(byte)' ',(byte)'W',(byte)'o',(byte)'r',(byte)'l',(byte)'d',};
private static final byte HW_CLA = (byte)0x80;
private static final byte HW_INS = (byte)0x00;
public static void install(byte[] bArray, short bOffset, byte bLength)
{
new HelloWorldApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
}
public void process(APDU apdu)
{
if (selectingApplet())
{
return;
}
byte[] buffer = apdu.getBuffer();
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS] & 0xFF);
if (CLA != HW_CLA)
{
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
switch ( INS )
{
case HW_INS:
getHelloWorld( apdu );
break;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void getHelloWorld( APDU apdu)
{
byte[] buffer = apdu.getBuffer();
short length = (short) helloWorld.length;
Util.arrayCopyNonAtomic(helloWorld, (short)0, buffer, (short)0, (short) length);
apdu.setOutgoingAndSend((short)0, length);
}
}
我明白了,但我不明白为什么程序员在行中使用&0XFF
:
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS] & 0xFF);
为什么他通常不使用下面这行?
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA]);
byte INS = (byte) (buffer[ISO7816.OFFSET_INS]);
并且也在行中:
ew HelloWorldApplet().register(bArray, (short) (bOffset + 1), bArray[bOffset]);
+1
是什么意思?
虽然我们看不到作者的意图,但行:
byte CLA = (byte) (buffer[ISO7816.OFFSET_CLA] & 0xFF);
100% 等同于:
byte CLA = buffer[ISO7816.OFFSET_CLA];
Java确实经常使用整数作为运算结果,并且由于Java卡通常不支持int
值,因此经常需要转换为byte
或 short
。我只能猜测 & 0xFF
和演员表的存在是因为过于热心地试图摆脱中间 int
值。让 Java 支持无符号字节也可能是一个糟糕的尝试。
register
方法需要实例 AID。该 AID 在全球平台 INSTALL for INSTALL
期间给出的用户参数范围内,但它前面有一个包含 AID 长度的字节(介于 5 和 15 之间,包括在内)。所以 + 1
是跳过那个长度字节——它又出现在 register
方法的最后一个参数中:bArray[bOffset]
.