2016-12-22 2 views
2

Ich habe eine Byte-Array mit dem Namen 'Hexa', die durch einige Prozesse und Array 'Hexa1' wird produziert. packPDU gibt ein Zeichenfolgenarray zurück, das hexadezimal in Form von Zeichen ist. Ich möchte das Format von 'hexa1' folgt, so dass sie als Zahlen interpretiert werden können:Konvertieren von Hex-Zeichenfolge in Byte-Array in Javacard

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

Es folgt der Code verwende ich:

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; 
} 

}

Antwort

1

Ich habe setze dies durch Java SE Tests, aber ich habe es noch nicht auf Java Card hochgeladen. Paul Bastian scheint dies jedoch getan zu haben.

Kommentare zur Hex-Konvertierung sind innerhalb des Codes. Hoffentlich es zeigt auch einige bewährte Programmierpraktiken:

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

Das schöne Code Maartens, eine kurze Besetzung für out.length fehlt –

+0

ich Angst davor war. Ich werde versuchen, diesen Abend zu ändern ... Sie sind frei, die Antwort natürlich zu bearbeiten. –

Verwandte Themen