2016-12-22 25 views
2

我有一個名爲'hexa'的字節數組,它經過一些進程併產生數組'hexa1'。 packPDU返回字符串形式的十六進制字符串數組。我想「hexa1」的格式進行以下,使他們可以被解釋爲數字:將十六進制字符串轉換爲javacard中的字節數組

byte[] hexa1 = { (byte) 0x0F, (byte) 0xAA, (byte) 0x5C, (byte) 0x4E, (byte) 0x45 ,(byte) 0xA3, (byte) 0XA9, (byte) 0x68}; 

以下是我使用的代碼:

package com.bittest; 



public class aditya1 { 
public static void main(String[] args) { 

    byte[] hexa = {'A','9', 'G', 'F', 'B', 'C', 'D', 'E', '5', '1'}; 
    byte[] gsm= convertUnicode2GSM(hexa); 
    byte [] dst=new byte[gsm.length]; 
    byte[] packed_array = packPDU(gsm, (short) 0, dst, (short) 0, (short) dst.length) ; 

    byte[] hexa1 = new byte [(short)(packed_array.length/2)]; 
    for(short i =0; i<(short)((packed_array.length/2)-1); i++){ 
     hexa1[(short)(i+1)] = (byte)((short)(16*hexa[(short)(2*i+1)]) + (short)(hexa[(short)(2*i+2)])); 
    } 



} 

public static byte[] convertUnicode2GSM(byte[] msg) { 
     byte[] data = new byte[160]; 
     short j=0; 
     for (short i = 0; i <(short) msg.length; i++) { 
     switch (msg[i]) { 
     case (byte)'@': data[j] = 0x00; j++; break; 
     case (byte)'$': data[j] = 0x02; j++;break; 
     case (byte)'\n': data[j] = 0x0A; j++;break; 
     case (byte)'\r': data[j] = 0x0D; j++;break; 
     case (byte)'_': data[j] = 0x11; j++;break; 
     //case (byte) 'ß': data[j] = 0x1E; j++;break; 
     case (byte)' ': data[j] = 0x20; j++;break; 
     case (byte)'!': data[j] = 0x21; j++;break; 

     case (byte) '\"': data[j] = 0x22; j++;break; 
     case (byte)'#': data[j] = 0x23; j++;break; 
     case (byte)'%': data[j] = 0x25; j++;break; 
     case (byte)'&': data[j] = 0x26; j++;break; 
     case (byte)'\'': data[j] = 0x27; j++;break; 
     case (byte)'(': data[j] = 0x28; j++;break; 
     case (byte)')': data[j] = 0x29; j++;break; 
     case (byte) '*': data[j] = 0x2A; j++;break; 
     case (byte)'+': data[j] = 0x2B; j++;break; 
     case (byte)',': data[j] = 0x2C; j++;break; 
     case (byte)'-': data[j] = 0x2D; j++;break; 
     case (byte) '.': data[j] = 0x2E; j++;break; 
     case (byte)'/': data[j] = 0x2F; j++;break; 
     case (byte)'0': data[j] = 0x30; j++;break; 
     case (byte)'1': data[j] = 0x31; j++;break; 
     case (byte)'2': data[j] = 0x32; j++;break; 
     case (byte)'3': data[j] = 0x33; j++;break; 
     case (byte)'4': data[j] = 0x34; j++;break; 
     case (byte)'5': data[j] = 0x35; j++;break; 
     case (byte)'6': data[j] = 0x36; j++;break; 
     case (byte)'7': data[j] = 0x37; j++;break; 
     case (byte)'8': data[j] = 0x38; j++;break; 
     case(byte) '9': data[j] = 0x39; j++;break; 
     case (byte)':': data[j] = 0x3A; j++;break; 
     case (byte)';': data[j] = 0x3B; j++;break; 
     case (byte)'<': data[j] = 0x3C; j++;break; 
     case (byte)'=': data[j] = 0x3D; j++;break; 
     case (byte)'>': data[j] = 0x3E; j++;break; 
     case (byte)'?': data[j] = 0x3F; j++;break; 
     case (byte)'A': data[j] = 0x41; j++;break; 
     case (byte)'B': data[j] = 0x42; j++;break; 
     case (byte)'C': data[j] = 0x43; j++;break; 
     case (byte)'D': data[j] = 0x44; j++;break; 
     case (byte)'E': data[j] = 0x45; j++;break; 
     case (byte)'F': data[j] = 0x46; j++;break; 
     case (byte)'G': data[j] = 0x47; j++;break; 
     case (byte)'H': data[j] = 0x48; j++;break; 
     case (byte)'I': data[j] = 0x49; j++;break; 
     case (byte)'J': data[j] = 0x4A; j++;break; 
     case (byte)'K': data[j] = 0x4B; j++;break; 
     case (byte)'L': data[j] = 0x4C; j++;break; 
     case (byte)'M': data[j] = 0x4D; j++;break; 
     case (byte)'N': data[j] = 0x4E; j++;break; 
     case (byte)'O': data[j] = 0x4F; j++;break; 
     case (byte)'P': data[j] = 0x50; j++;break; 
     case (byte)'Q': data[j] = 0x51; j++;break; 
     case (byte)'R': data[j] = 0x52; j++;break; 
     case (byte)'S': data[j] = 0x53; j++;break; 
     case (byte)'T': data[j] = 0x54; j++;break; 
     case (byte)'U': data[j] = 0x55; j++;break; 
     case (byte)'V': data[j] = 0x56; j++;break; 
     case (byte)'W': data[j] = 0x57; j++;break; 
     case (byte)'X': data[j] = 0x58; j++;break; 
     case (byte)'Y': data[j] = 0x59; j++;break; 
     case (byte)'Z': data[j] = 0x5A; j++;break; 
    // case (byte) 'Ü': data[j] = 0x5E; j++;break; 
    // case (byte) '§': data[j] = 0x5F; j++;break; 
     case (byte)'a': data[j] = 0x61; j++;break; 
     case (byte)'b': data[j] = 0x62; j++;break; 
     case (byte) 'c': data[j] = 0x63; j++;break; 
     case (byte)'d': data[j] = 0x64; j++;break; 
     case (byte)'e': data[j] = 0x65; j++;break; 
     case (byte)'f': data[j] = 0x66; j++;break; 
     case (byte)'g': data[j] = 0x67; j++;break; 
     case (byte)'h': data[j] = 0x68; j++;break; 
     case (byte)'i': data[j] = 0x69; j++;break; 
     case (byte)'j': data[j] = 0x6A; j++;break; 
     case (byte)'k': data[j] = 0x6B; j++;break; 
     case (byte)'l': data[j] = 0x6C; j++;break; 
     case (byte)'m': data[j] = 0x6D; j++;break; 
     case (byte)'n': data[j] = 0x6E; j++;break; 
     case (byte)'o': data[j] = 0x6F; j++;break; 
     case (byte)'p': data[j] = 0x70; j++;break; 
     case (byte)'q': data[j] = 0x71; j++;break; 
     case (byte)'r': data[j] = 0x72; j++;break; 
     case (byte)'s': data[j] = 0x73; j++;break; 
     case (byte)'t': data[j] = 0x74; j++;break; 
     case (byte)'u': data[j] = 0x75; j++;break; 
     case (byte)'v': data[j] = 0x76; j++;break; 
     case (byte)'w': data[j] = 0x77; j++;break; 
     case (byte)'x': data[j] = 0x78; j++;break; 
     case (byte)'y': data[j] = 0x79; j++;break; 
     case (byte)'z': data[j] = 0x7A; j++;break; 
     case (byte) '|': 
         data[j] = 0x1B; 
         j +=1; 
         data[j] = 0x40; 

         j++; 
         break; 


     default: data[j] = 0x3F; j++;break; // '?' 
     } // switch 
     } // for 
     return data; 

     } // convertUnicode2GSM 

public static byte[] packPDU(byte[] src, short offsetSrc, byte[] dst, short offsetDst, short length) { 

    short countSrc = (short) 0; 
    short countDst = (short) 0; 
    short countCurrent; 
    byte leftover = (byte) 0; 

    while (countSrc < length) { 
     countCurrent = (byte) (countSrc & 7); 
     if (countCurrent == 0) { 
      leftover = src[(short) (offsetSrc)]; 
     } else { 
      dst[offsetDst] = (byte) ((src[offsetSrc] << (8 - countCurrent)) | leftover); 
      leftover = (byte) (src[offsetSrc] >> countCurrent); 
      offsetDst++; 
      countDst++; 
     } 
     countSrc++; 
     offsetSrc++; 
    } 

    if ((length % 8) != 0) { 
     dst[offsetDst] = leftover; 
     countDst++; 
    } 

    return dst; 
} 

}

回答

1

我已經通過Java SE測試,但我還沒有上傳到Java Card。保羅巴斯蒂安似乎也這樣做了。

十六進制轉換的註釋在代碼中。但願它也顯示了一些最佳的編程實踐:

public final class HexCodec { 

    private static final short NIBBLE_SIZE = 4; 

    public static final short REASON_DATA_BUFFER_NOT_LARGE_ENOUGH = 0x0001; 
    public static final short REASON_INVALID_ENCODING_SIZE = 0x0002; 
    public static final short REASON_INVALID_ENCODING_CHARACTER = 0x0003; 
    public static final short REASON_INVALID_DATA_SIZE = 0x0004; 

    /** 
    * Decodes the hexadecimal encoded bytes in the input buffer and puts them 
    * in the output buffer. 
    * Hex digits need to be ASCII encoded and the letters need to be uppercase. 
    * Each byte needs to be encoded using exactly two hexadecimal digits. 
    * WARNING: this function doesn't currently validate offset and length 
    * arguments. 
    * 
    * @param in 
    *   the input buffer 
    * @param inOff 
    *   the offset in the input buffer containing the hexadecimal 
    *   bytes 
    * @param inLen 
    *   the length in the input buffer of the hexadecimal bytes 
    * @param out 
    *   the output buffer 
    * @param outOff 
    *   the offset in the output buffer of the decoded bytes 
    * @return the length in the output buffer of the decoded bytes 
    * @throws CardRuntimeException 
    *    with the following reason codes: 
    *    <nl> 
    *    <li> 
    *    {@link HexCodec#REASON_INVALID_ENCODING_SIZE} : if the 
    *    encoding size is not a multiple of 2</li> 
    *    <li> 
    *    {@link HexCodec#REASON_DATA_BUFFER_NOT_LARGE_ENOUGH} : if 
    *    the output buffer cannot hold the decoded data</li> 
    *    <li> 
    *    {@link HexCodec#REASON_INVALID_ENCODING_CHARACTER} : if 
    *    the encoding contains characters outside the uppercase 
    *    hexadecimals</li> 
    *    </nl> 
    */ 
    private static short fromUppercaseHex(final byte[] in, final short inOff, 
      final short inLen, 
      final byte[] out, final short outOff) { 

     // doesn't validate offsets in buffer 

     // odd number of hex characters not allowed 
     if (inLen % 2 != 0) { 
      throw createCardRuntimeException(REASON_INVALID_ENCODING_SIZE); 
     } 

     final short outLen = (short) (inLen/2); 

     // make sure we have enough room in the buffer *before* decoding 
     final short outEnd = (short) (outOff + outLen); 
     if (outEnd < 0 
       || outEnd > (short) out.length) { 
      throw createCardRuntimeException(REASON_DATA_BUFFER_NOT_LARGE_ENOUGH); 
     } 

     // main decode loop 
     for (short i = 0; i < outLen; i++) { 
      byte b; 

      // decodes high nibble of b 
      final byte hexHi = in[(short) (inOff + i * 2)]; 
      if (hexHi >= '0' && hexHi <= '9') { 
       b = (byte) ((hexHi - '0') << NIBBLE_SIZE); 
      } else if (hexHi >= 'A' && hexHi <= 'F') { 
       b = (byte) ((hexHi - 'A' + 10) << NIBBLE_SIZE); 
      } else { 
       throw createCardRuntimeException(REASON_INVALID_ENCODING_CHARACTER); 
      } 

      // decodes low nibble of b 
      final byte hexLo = in[(short) (inOff + i * 2 + 1)]; 
      if (hexLo >= '0' && hexLo <= '9') { 
       b |= (byte) (hexLo - '0'); 
      } else if (hexLo >= 'A' && hexLo <= 'F') { 
       b |= (byte) (hexLo - 'A' + 10); 
      } else { 
       throw createCardRuntimeException(REASON_INVALID_ENCODING_CHARACTER); 
      } 

      out[(short) (outOff + i)] = b; 
     } 

     return outLen; 
    } 

    /** 
    * Encodes the bytes in the input buffer and puts the hexadecimals in the 
    * output buffer. 
    * The hex digits will be ASCII encoded and the letters will be in 
    * uppercase. 
    * Each byte will be encoded using exactly two hexadecimal digits. 
    * WARNING: this function doesn't currently validate offset and length 
    * arguments. 
    * 
    * @param in 
    *   the input buffer 
    * @param inOff 
    *   the offset in the input buffer containing the binary data 
    *   bytes 
    * @param inLen 
    *   the length in the input buffer of the binary data 
    * @param out 
    *   the output buffer 
    * @param outOff 
    *   the offset in the output buffer for the hexadecimal digits 
    * @return the number of hexadecimal digits 
    * @throws CardRuntimeException 
    *    with the following reason codes: 
    *    <nl> 
    *    <li> 
    *    {@link HexCodec#REASON_INVALID_DATA_SIZE} : if the output 
    *    buffer cannot hold the encoded data</li> 
    *    </nl> 
    */ 
    private static short toUppercaseHex(
      final byte[] in, final short inOff, final short inLen, 
      final byte[] out, final short outOff) { 

     // doesn't validate offsets in buffer 

     final short outLen = (short) (inLen * 2); 
     final short outEnd = (short) (outOff + outLen); 

     // make sure we have enough room in the buffer *before* decoding 
     if (outEnd < 0 || outEnd > (short) out.length) { 
      throw createCardRuntimeException(REASON_INVALID_DATA_SIZE); 
     } 

     // main encode loop 
     for (short i = 0; i < inLen; i++) { 
      final byte b = in[(short) (inOff + i)]; 

      // encodes high nibble of b 
      final byte bHi = (byte) ((b >> NIBBLE_SIZE) & 0x0F); 
      if (bHi < 10) { 
       out[(short) (outOff + i * 2)] = (byte) ('0' + bHi); 
      } else { 
       out[(short) (outOff + i * 2)] = (byte) ('A' + bHi - 10); 
      } 

      // encodes low nibble of b 
      final byte bLo = (byte) (b & 0x0F); 
      if (bLo < 10) { 
       out[(short) (outOff 
         + i * 2 + 1)] = (byte) ('0' + bLo); 
      } else { 
       out[(short) (outOff 
         + i * 2 + 1)] = (byte) ('A' + bLo - 10); 
      } 
     } 

     return outLen; 
    } 

    /** 
    * Creates a CardRuntimeException with the given reason code and returns it 
    * so it can be thrown. 
    * This alleviates the issue of the Java compiler not recognizing `throwIt` 
    * as exit point. 
    * WARNING: do not forget to actually throw the exception returned. 
    * 
    * @param reason 
    *   the reason code of the exception 
    * @return the exception generated by the runtime environment (through 
    *   <code>CardRuntimeException.throwIt</code>) 
    */ 
    private static CardRuntimeException createCardRuntimeException(
      final short reason) { 
     try { 
      CardRuntimeException.throwIt(reason); 
     } catch (CardRuntimeException e) { 
      return e; 
     } 
     // should never be reached (but the compiler doesn't know that) 
     return null; 
    } 

    private HexCodec() { 
     // avoid instantiation 
    } 
} 
+0

這是漂亮的代碼馬騰,缺少一個短塑像爲out.length –

+0

我怕的就是這個。我今天晚上會試着修改......當然你可以自由編輯答案。 –

相關問題