在JavaCard平台上将基数10数字转换为基数256数字

问题描述:

我想将大数字的ascii表示转换为基本的256字节数组表示形式。在JavaCard平台上将基数10数字转换为基数256数字

更精确的:为了满足以下测试。

JavaCard平台上可用的最大数字类型很短。

限制:我没有javacardx.framework.math.BigNumber可用。我已经有了添加两个字节数组的方法。 add(byte[], byte[])

@Test 
public void convertAsciiNumber1234567890ToByteArray() { 

    byte[] asciiAmount = new byte[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; 

    byte[] result = ArrayUtil.convertAsciiAmount(asciiAmount, (short) 8); 

    byte[] expected = new byte[]{0x00, 0x00, 0x00, 0x00, 0x49, (byte) 0x96, 0x02, (byte) 0xd2}; 
    assertEquals(expected[0], result[0]); 
    assertEquals(expected[1], result[1]); 
    assertEquals(expected[2], result[2]); 
    assertEquals(expected[3], result[3]); 
    assertEquals(expected[4], result[4]); 
    assertEquals(expected[5], result[5]); 
    assertEquals(expected[6], result[6]); 
    assertEquals(expected[7], result[7]); 
} 

ArrayUtil.convertAsciiAmount的第二个参数是结果数组的长度。

基本思想是,一旦您将结果设置为第一个十进制数字,然后循环剩下的数字,将结果乘以10并添加当前数字。

乘法和加法例程使用标准的“大整数”算法。请注意,您需要将中间结果保存在下一个最大的整数表示中,在这种情况下该表达式很短。

您可以修改此代码,以便您不必预先分配结果数组,而是每次需要时都会增加它。

public class DecToHex 
{ 
    static int BASE = 0xFF; 
    static int SHIFT = 8; 

    public static void main(String[] args) 
    { 
     byte[] ascii = new byte[]{'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; 
     byte[] result = convertAsciiAmount(ascii, (byte)8); 
     printAsHex(result); 
    } 

    static byte[] convertAsciiAmount(byte[] ascii, byte capacity) 
    { 
     byte len = 0; 
     byte[] result = new byte[capacity]; 

     result[0] = (byte)(ascii[0]-'0'); 
     for(byte i=1; i<ascii.length; i++) 
     { 
      byte digit = (byte)(ascii[i]-'0'); 

      // multiply result by 10 
      len += 1;   
      short prod = 0; 
      for(byte j=0; j<len; j++) 
      { 
       prod += (10 * (result[j] & BASE)); 
       result[j] = (byte)prod; 
       prod >>>= SHIFT; 
      } 
      result[len] = (byte)prod;   
      while(len > 0 && result[len-1] == 0) len--; 

      // add current digit    
      short sum = 0; 
      sum += (result[0] & BASE) + (digit & BASE); 
      result[0] = (byte)sum; 
      sum >>>= SHIFT; 

      for(byte j=1; j<len; j++) 
      { 
       sum += (result[j] & BASE); 
       result[j] = (byte)sum; 
       sum >>>= SHIFT; 
      } 

      if(sum > 0) 
      { 
       result[len++] = (byte)sum; 
      } 
     }  
     return result; 
    } 

    static void printAsHex(byte[] hex) 
    { 
     for(byte i=(byte)(hex.length-1); i>=0; i--) 
     { 
      System.out.print(String.format("0x%02X", (hex[i] & BASE)) + " "); 
     } 
     System.out.println();  
    } 
} 

输出:

0x00 0x00 0x00 0x00 0x49 0x96 0x02 0xD2 
+0

谢谢! convertAsciiAmount()几乎可以工作,我只需要反转结果并在需要的地方用short代替int。无论如何,我会接受你的答案。 –

+0

对不起,我觉得用小端来思考要容易得多,但你想要一个大端的结果。正如你所说,你可以扭转结果。 – SirRaffleBuffle