2014-01-20 1 views
0

java 카드 2.2.1을 사용하여 4 바이트 16 진수를 10 진수로 변환하려고합니다.Java Card 2.2.1에서 큰 (32 비트 이상) 숫자로 계산할 수있는 방법이 있습니까?

예컨대 : 50ef7f19 - 내가 그것을 정수로 데이터 형식을 사용하는 것이 좋습니다 있도록 32 비트 번호를 사용하기 위해 필요한이 전환> 1357872921

. 하지만 난 자바 카드에서 'int'의 사용에 대해 잘 모르겠습니다. 이 명세서에서 '선택 사항'은 정수로 표현된다. 그것을 사용하는 제한은 무엇입니까? int를 사용하지 않는다면 큰 숫자로 계산할 수있는 다른 방법이 있습니까?

+0

옵션은 Java Card가'int' 타입을 지원할 수도 있고 지원하지 않을 수도 있음을 의미합니다. int가 필요한 경우이를 지원하는 올바른 카드를 구입해야합니다. – Robert

답변

2

Java Card Classic에서 int을 사용할 때 가장 큰 제한은 Java Card Classic을 구현하는 대부분의 스마트 카드에서 지원되지 않는다는 것입니다. 다른 큰 제약은 API가 정수를 거의 지원하지 않는다는 것입니다. 따라서 정수 연산을 사용할 수 있더라도 API는 바이트 또는 단락 만 허용합니다.

저는 관심있는 경우 32 비트 산술을 수행 할 수있는 JCInteger이라는 특수 클래스를 만들었습니다. 아직 테스트 케이스를 게시하지 않았으므로주의해서 사용하십시오. 물론 정수 연산을 수행하는 비슷한 방법을 만들 수 있습니다. 만약 당신이 (매우) 행운이라면 칩은 BigNumber을 구현할 수도 있습니다.

처음에는 16 진수 (ASCII 또는 ASCII 호환 인코딩)를 나타내는 바이트에서 바이트로 이동할 수 있습니다. 나중에 필요할 때만 정수를 사용해야합니다. 일반적으로 16 진수에서 16 진수로의 변환은 스마트 카드가 아닌 단말기에서 수행됩니다.


원하는 경우 빠른 (최소 분기 수)이지만 16 진수에서 바이트를 생성하는 바이트 코드 집약적 인 방법입니다. 짝수 바이트 수를 공급하는 것을 잊지 마세요. offsetlength 매개 변수를 믹스에 추가 할 수 있습니다.

경고 : 테스트되지 않은 배열 (디코딩 테스트)

public static short fromHex(final byte[] hex, short hexOff, final short hexLen, final byte[] bin, short binOff) { 

    // reuses offsets parameters for reasons of (unproven) optimization 

    // === check hex input parameters === 
    if (hexOff < 0 || hexOff >= hex.length) { 
     CardRuntimeException.throwIt((short) 'H'); 
    } 

    final short hexEnd = (short) (hexOff + hexLen); 
    if (hexLen < 0 || hexEnd > hex.length || hexEnd < 0 || hexLen % 2 != 0) { 
     CardRuntimeException.throwIt((short) 'H'); 
    } 

    // === calculate final output size === 
    final short binLen = (short) (hex.length/2); 

    // === check bin output parameters === 
    if (binOff < 0 || binOff > bin.length) { 
     CardRuntimeException.throwIt((short) 'H'); 
    } 

    if (binOff + binLen > bin.length || binOff + binLen < 0) { 
     CardRuntimeException.throwIt((short) 'H'); 
    } 

    // === main loop === 

    // pre-create the array 
    // set validity = 0 (0 = valid, anything else is not valid) 
    short validity = 0; 
    short c, isLetter, value, validDigitStruct, validDigit, validLetterStruct, validLetter; 
    while (hexOff < hexEnd) { 

     // --- calculate the value of the higher (more significant) tuple --- 

     c = hex[hexOff]; 

     // check using calculation over bits to see if first char is a letter 
     // isLetter is zero if it is a digit, 1 if it is a letter (upper & lowercase) 
     isLetter = (short) ((c >> 6) & 1); 

     // calculate the tuple value using a multiplication to make up the difference between 
     // a digit character and an alpha-numerical character 
     // minus 1 for the fact that the letters are not zero based 
     value = (short) (((c & 0xF) + isLetter * (-1 + 10)) << 4); 

     // check validity of all the other bits 
     validity |= c >>> 7; 

     validDigitStruct = (short) ((c & 0x30)^0x30); 
     validDigit = (short) (((c & 0x8) >> 3) * (c & 0x6)); 
     validity |= (isLetter^1) * (validDigitStruct | validDigit); 

     validLetterStruct = (short) (c & 0x18); 
     validLetter = (short) ((((c - 1) & 0x4) >> 2) * ((c - 1) & 0x2)); 
     validity |= isLetter * (validLetterStruct | validLetter); 

     // --- do the same with the lower (less significant) tuple --- 

     c = hex[(short) (hexOff + 1)]; 
     isLetter = (short) ((c >> 6) & 1); 
     value ^= (c & 0xF) + isLetter * (-1 + 10); 
     bin[binOff] = (byte) value; 

     // check validity of all the other bits 
     validity |= c >>> 7; 

     validDigitStruct = (short) ((c & 0x30)^0x30); 
     validDigit = (short) (((c & 0x8) >> 3) * (c & 0x6)); 
     validity |= (isLetter^1) * (validDigitStruct | validDigit); 

     validLetterStruct = (short) (c & 0x18); 
     validLetter = (short) ((((c - 1) & 0x4) >> 2) * ((c - 1) & 0x2)); 
     validity |= isLetter * (validLetterStruct | validLetter); 

     // --- update offsets --- 

     hexOff += 2; 
     binOff++; 
    } 

    if (validity != 0) { 
     // rewrite this for java card using e.g. CardRuntimeException.throwIt(short reason) 
     CardRuntimeException.throwIt((short) 'H'); 
    } 

    return binLen; 
} 
1

만 (바이트 배열) 진수 문자열로 진수 바이트를 변환 할 경우, 다음과 같은 코드를 사용할 수 있습니다 처리 :

static byte[] output = new byte[10]; 
static short[] input = new short[4]; 

// the weights table for hex byte: 256^1 = 256, 256^2 = 65536, and 256^3 = 16777216 
// 256^0 is moved outside the table for optimization (assigned as initial result value) 
public static byte[] weight = { 
     6, 6, 6, 
     1, 3, 5, 
     2, 5, 2, 
     7, 5, 0, 
     7, 6, 0, 
     7, 0, 0, 
     6, 0, 0, 
     1, 0, 0, 
     0, 0, 0, 
     0, 0, 0 
}; 

// the method to convert 4 bytes of hex into decimal string (10 byte arrays) 
// final result is stored in output byte array 
public static void convertHexToDecimalString(byte[] hex) { 

    // convert input to positive (byte array to short array) 
    for (byte i = 0; i < 4; i++) { 
     input[i] = (short) (hex[i] & 0x00FF); 
    } 

    // assign the least significant hex byte to result 
    short result = input[3]; 
    byte offset = 0; 

    // loop to calculate and assign each decimal digit  
    for (byte i = 0; i < 10; i++) { 
     result = (short) ((weight[offset] * input[0]) 
       + (weight[offset + 1] * input[1]) 
       + (weight[offset + 2] * input[2]) + result); 
     output[9 - i] = (byte) (0x30 + result % 10); 
     result /= 10; 

     offset += 3; 
    } 
} 
+0

내 코드가 완벽하지는 않습니다. (필자가 지금까지 저의 답에서 언급했듯이) 자바 카드에 정적 바이트 배열을 쓰는 것은 좋은 생각이 아닙니다. (자바 카드 표준에 따르면 불법이기 때문에. 배열은 영구 메모리 (플래시의 EEPROM)에있을 것입니다. –

+0

정적 바이트 배열은 일반적으로보다 효율적인 코드를 생성합니다. 애플릿 삭제가 문제 중 하나라면 제거 방법에서 바이트 배열을 무효화 할 수 있습니다. 물론 수정할 수 있습니다 예를 들어, 더 빠르고 더 빈번한 계산을 위해 RAM 바이트 배열을 사용하려는 경우. – David