我是新手小程序,我使用此链接:working with Java Card
Wallet创建了一个电子钱包项目。
之前我可以通过此命令获得信用卡金额:80 30 00 00 01 1A 00
。
我现在想要添加'5000'到现在的金额。如你所知,十六进制中的5000等于
'1388'
为2字节。所以我必须将2字节数据13和88发送到卡上。
我创建了波纹管命令并将其发送到卡但我得到'67 00错误的长度'
响应。
80 30 00 00 02 13 88 00
我如何向卡上/从卡中扣除1个字节以上的信用卡或借记卡?
答案 0 :(得分:2)
您必须更改当前指向的Applet的代码:
if ((numBytes != 1) || (byteRead != 1)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); // constant with value 0x6700
}
所以你必须确保它允许发送2个字节,然后你可以使用Util.getShort
方法将字节转换为16位有符号值(使用大端二补码表示法,像往常一样)。
答案 1 :(得分:1)
将creadit()
方法替换为此方法。但请记住,您必须使用两个字节的值来记入您今后的壁垒。 (即使是小于255或0xFF的值。即你必须使用0x00FF
以255美元从钱包中扣款。
private void credit(APDU apdu) {
// access authentication
if (!pin.isValidated()) {
ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
}
byte[] buffer = apdu.getBuffer();
// Lc byte denotes the number of bytes in the
// data field of the command APDU
byte numBytes = buffer[ISO7816.OFFSET_LC];
// indicate that this APDU has incoming data
// and receive data starting from the offset
// ISO7816.OFFSET_CDATA following the 5 header
// bytes.
byte byteRead = (byte) (apdu.setIncomingAndReceive());
// it is an error if the number of data bytes
// read does not match the number in Lc byte
if ((numBytes != 2) || (byteRead != 2)) {
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
}
// get the creditBytes
byte[] creditBytes = new byte[2];
creditBytes[0]=buffer[ISO7816.OFFSET_CDATA];
creditBytes[1]=buffer[ISO7816.OFFSET_CDATA+1];
// convert 2 byte of creatBytes to a single short value.
short creditAmount = Util.getShort(creditBytes,(short)0);
// check the credit amount
if ((creditAmount > MAX_TRANSACTION_AMOUNT) || (creditAmount < 0)) {
ISOException.throwIt(SW_INVALID_TRANSACTION_AMOUNT);
}
// check the new balance
if ((short) (balance + creditAmount) > MAX_BALANCE) {
ISOException.throwIt(SW_EXCEED_MAXIMUM_BALANCE);
}
// credit the amount
balance = (short) (balance + creditAmount);
}
答案 2 :(得分:0)
我建议使用BCD加法和BCD减法,如下:
以下是实施示例。它尚未经过测试,但应该让您知道它是如何工作的:
public class BCD {
public static final short NUMBER_OF_BYTES = 6;
static void add(byte[] augend, byte[] addend, byte[] result) {
byte carry = 0;
short temp = 0;
for (short i = (short) (NUMBER_OF_BYTES - 1); i >= 0; i--) {
temp = (short) (decode(augend[i]) + decode(addend[i]) + carry);
carry = (byte) ((temp > 100) ? 1 : 0);
result[i] = encode((byte) temp);
}
if (carry == 1) {
// TODO: result more than maximum
// you can set all digits to 9 or throw exception
}
}
static void subtract(byte[] minuend, byte[] subtrahend, byte[] result) {
byte borrow = 0;
short temp = 0;
for (short i = (short) (NUMBER_OF_BYTES - 1); i >= 0; i--) {
temp = (short) (100 + decode(minuend[i]) - decode(subtrahend[i]) - borrow);
borrow = (byte) ((temp < 100) ? 1 : 0);
result[i] = encode((byte) temp);
}
if (borrow == 1) {
// TODO: subtrahend > minuend,
// you can set all digits to 0 or throw exception
}
}
static byte encode(byte value) {
value %= 100; // only convert two digits, ignore borrow/carry
return (byte) (((value / 10) << 4) | (value % 10));
}
static byte decode(byte bcdByte) {
byte highNibble = (byte) ((bcdByte >> 4) & 0x0F);
byte lowNibble = (byte) (bcdByte & 0x0F);
if ((highNibble > 9) || (lowNibble > 9)) {
// found 'A' to 'F' character which should be invalid
// you can change this line, e.g. throwing exception
return 0;
}
return (byte) ((highNibble * 10) + lowNibble);
}
}