磁条卡磁道笔记(2)
上一篇文章
磁条卡磁道笔记(1)之后,现在接着具体讲讲三个磁道的数据解析代码。没错,本文只是代码……单纯的代码……
1、第1磁道数据
public void fromByteArray(byte[] buffer, int offset, int byteCount) {
/* Check the parameters. */
if ((buffer == null) || (offset < 0) || (byteCount < 0)
|| (offset + byteCount > buffer.length)) {
return;
}
init();
int index = 0;
char track1Jis2Char = 0;
char track1Char = 0;
Track1State state = Track1State.START;
int charCount = 0;
/* Convert the byte to character. */
for (index = 0; index < byteCount; index++) {
track1Jis2Char = (char) (buffer[offset + index] & 0x7F);
track1Char = TRACK1_CHAR_TABLE[buffer[offset + index] & 0x3F];
mTrack1data += track1Char;
switch (state) {
case START:
if (buffer[offset + index] == (byte) 0xFF) {
state = Track1State.JIS2_DATA;
} else {
if (track1Char == START_SENTINEL) {
state = Track1State.FORMAT_CODE;
}
}
break;
case JIS2_DATA:
if (buffer[offset + index] == (byte) 0xFF) {
state = Track1State.END;
} else {
mJis2Data += Character.isISOControl(track1Jis2Char) ? ' '
: track1Jis2Char;
}
break;
case FORMAT_CODE:
state = Track1State.PRIMARY_ACCOUNT_NUMBER;
break;
case PRIMARY_ACCOUNT_NUMBER:
if (track1Char == FIELD_SEPARATOR) {
state = Track1State.NAME;
} else {
mPrimaryAccountNumber += track1Char;
}
break;
case NAME:
if (track1Char == FIELD_SEPARATOR) {
charCount = 4;
state = Track1State.EXPIRATION_DATE;
} else {
mName += track1Char;
}
break;
case EXPIRATION_DATE:
mExpirationDate += track1Char;
charCount--;
if (charCount <= 0) {
charCount = 3;
state = Track1State.SERVICE_CODE;
}
break;
case SERVICE_CODE:
mServiceCode += track1Char;
charCount--;
if (charCount <= 0) {
state = Track1State.DISCRETIONARY_DATA;
}
break;
case DISCRETIONARY_DATA:
if (track1Char == END_SENTINEL) {
state = Track1State.END;
} else {
mDiscretionaryData += track1Char;
}
break;
default:
break;
}
}
}
2、第2磁道数据
public void fromByteArray(byte[] buffer, int offset, int byteCount) {
/* Check the parameters. */
if ((buffer == null) || (offset < 0) || (byteCount < 0)
|| (offset + byteCount > buffer.length)) {
return;
}
init();
int index = 0;
char track2Char = 0;
Track2State state = Track2State.START;
int charCount = 0;
/* Convert the byte to character. */
for (index = 0; index < byteCount; index++) {
track2Char = TRACK2_CHAR_TABLE[buffer[offset + index] & 0x0F];
mTrack2data += track2Char;
switch (state) {
case START:
if (track2Char == START_SENTINEL) {
state = Track2State.PRIMARY_ACCOUNT_NUMBER;
}
break;
case PRIMARY_ACCOUNT_NUMBER:
if (track2Char == FIELD_SEPARATOR) {
charCount = 4;
state = Track2State.EXPIRATION_DATE;
} else {
mPrimaryAccountNumber += track2Char;
}
break;
case EXPIRATION_DATE:
mExpirationDate += track2Char;
charCount--;
if (charCount <= 0) {
charCount = 3;
state = Track2State.SERVICE_CODE;
}
break;
case SERVICE_CODE:
mServiceCode += track2Char;
charCount--;
if (charCount <= 0) {
state = Track2State.DISCRETIONARY_DATA;
}
break;
case DISCRETIONARY_DATA:
if (track2Char == END_SENTINEL) {
state = Track2State.END;
} else {
mDiscretionaryData += track2Char;
}
break;
default:
break;
}
}
}
3、第3磁道数据
public void fromByteArray(byte[] buffer, int offset, int byteCount) {
/* Check the parameters. */
if ((buffer == null) || (offset < 0) || (byteCount < 0)
|| (offset + byteCount > buffer.length)) {
return;
}
init();
int index = 0;
char track3Char = 0;
Track3State state = Track3State.START;
int charCount = 0;
/* Convert the byte to character. */
for (index = 0; index < byteCount; index++) {
track3Char = TRACK3_CHAR_TABLE[buffer[offset + index] & 0x0F];
mTrack3data += track3Char;
switch (state) {
case START:
if (track3Char == START_SENTINEL) {
charCount = 2;
state = Track3State.FORMAT_CODE;
}
break;
case FORMAT_CODE:
charCount--;
if (charCount <= 0) {
state = Track3State.PRIMARY_ACCOUNT_NUMBER;
}
break;
case PRIMARY_ACCOUNT_NUMBER:
if (track3Char == FIELD_SEPARATOR) {
charCount = 3;
state = Track3State.COUNTRY_CODE;
} else {
mPrimaryAccountNumber += track3Char;
}
break;
case COUNTRY_CODE:
mCountryCode += track3Char;
charCount--;
if (charCount <= 0) {
charCount = 3;
state = Track3State.CURRENCY_CODE;
}
break;
case CURRENCY_CODE:
mCurrencyCode += track3Char;
charCount--;
if (charCount <= 0) {
state = Track3State.AMOUNT_INDEX;
}
break;
case AMOUNT_INDEX:
mAmountIndex += track3Char;
charCount = 4;
state = Track3State.PERIOD_AUTHORITY;
break;
case PERIOD_AUTHORITY:
mPeriodAuthority += track3Char;
charCount--;
if (charCount <= 0) {
charCount = 4;
state = Track3State.PERIOD_BALANCE;
}
break;
case PERIOD_BALANCE:
mPeriodBalance += track3Char;
charCount--;
if (charCount <= 0) {
charCount = 4;
state = Track3State.PERIOD_BEGIN_DATE;
}
break;
case PERIOD_BEGIN_DATE:
mPeriodBeginDate += track3Char;
charCount--;
if (charCount <= 0) {
charCount = 2;
state = Track3State.PERIOD_LENGTH;
}
break;
case PERIOD_LENGTH:
mPeriodLength += track3Char;
charCount--;
if (charCount <= 0) {
state = Track3State.PSW_INPUT_TIMES;
}
break;
case PSW_INPUT_TIMES:
mPswInputTimes += track3Char;
charCount = 6;
state = Track3State.P_AUTHORITY_CODE;
break;
case P_AUTHORITY_CODE:
mPAuthorityCode += track3Char;
charCount--;
if (charCount <= 0) {
state = Track3State.EXCHANGE_CONTROL_CODE;
}
break;
case EXCHANGE_CONTROL_CODE:
mExchangeControlCode += track3Char;
charCount = 2;
state = Track3State.PAN_TA_SR;
break;
case PAN_TA_SR:
mPanTaSr += track3Char;
charCount--;
if (charCount <= 0) {
charCount = 2;
state = Track3State.SAN_1_TA_SR;
}
break;
case SAN_1_TA_SR:
mSan1TaSr += track3Char;
charCount--;
if (charCount <= 0) {
charCount = 2;
state = Track3State.SAN_2_TA_SR;
}
break;
case SAN_2_TA_SR:
mSan2TaSr += track3Char;
charCount--;
if (charCount <= 0) {
charCount = 4;
state = Track3State.EXPIRATION_DATE;
}
break;
case EXPIRATION_DATE:
mExpirationDate += track3Char;
charCount--;
if (charCount <= 0) {
state = Track3State.SERIAL_NUMBER;
}
break;
case SERIAL_NUMBER:
mSerialNumber += track3Char;
state = Track3State.CODE_NUMBER;
break;
case CODE_NUMBER:
mCodeNumber += track3Char;
state = Track3State.SAN_1;
break;
case SAN_1:
if (track3Char == FIELD_SEPARATOR) {
state = Track3State.SAN_2;
} else {
mSan1 += track3Char;
}
break;
case SAN_2:
if (track3Char == FIELD_SEPARATOR) {
state = Track3State.PASS_MARK;
} else {
mSan2 += track3Char;
}
break;
case PASS_MARK:
mPassMark += track3Char;
charCount = 6;
state = Track3State.CRYPTOGRAPHIC_CHECK_DIGIT;
break;
case CRYPTOGRAPHIC_CHECK_DIGIT:
mCryptographicCheckDigit += track3Char;
charCount--;
if (charCount <= 0) {
state = Track3State.DISCRETIONARY_DATA;
}
break;
case DISCRETIONARY_DATA:
if (track3Char == END_SENTINEL) {
state = Track3State.END;
} else {
mDiscretionaryData += track3Char;
}
break;
default:
break;
}
}
}