2014-01-20 25 views
0

我想使用java卡2.2.1將4字節十六進制數轉換爲十進制數。有什麼辦法可以用Java卡2.2.1中的大(32位或更多)數進行計算嗎?

例如爲:50ef7f19 - > 1357872921

在該轉換我需要使用32位的數字,所以最好是使用數據類型爲整數。但我不確定在java卡中使用'int'。在說明中,「可選」用整數表示。使用它的限制是什麼?如果我不使用int,是否有任何其他方式來計算大數字?

+0

可選意味着您的JavaCard可能支持或不支持'int'類型。如果你需要int,你必須確保你購買了支持它的合適的卡。 – Robert

回答

2

在Java Card Classic上使用int的最大限制是它在實現Java Card Classic的大多數智能卡上不受支持。另一大限制是API幾乎不支持整數。因此,即使您可以使用整數算術,API也只接受字節或短語。

我創建了一個特殊的類JCInteger,如果您有興趣,它也能夠執行32位算術運算。儘管如此,我仍然沒有發佈我的測試用例,所以請謹慎使用。你當然可以創建類似的方法來執行整數運算。如果你(非常)幸運,你的芯片也可能實現BigNumber

請注意,最初您可以從代表十六進制字符(以ASCII或ASCII兼容編碼)的字節轉到字節。只有在需要之後,您纔可以使用整數。通常在終端執行十六進制字節轉換,而不是在智能卡內。


如果你有興趣,這裏是一個快速(分公司的最小數量),但是從十六進制字節生成的字節碼密集的方法。不要忘記給它提供偶數個字節,可能會添加一個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

不是我的代碼是完美的(正如我現在在我的回答中提到的那樣),但是寫入Java卡中的靜態字節數組並不是一個好主意(因爲根據Java Card標準它是非法的,該陣列將在持久性存儲器中(閃存的EEPROM) –

+0

靜態字節數組通常會產生更高效的代碼,如果applet刪除是問題之一,那麼我們可以在卸載方法中取消字節數組,當然它可以自由修改上面的代碼,例如,如果你想使用RAM字節數組更快和更頻繁的計算。 – David

相關問題