我有一个名为“hexa”的字节数组,它经过一些过程并生成数组“hexa1”。 packPDU 返回一个字符串数组,该数组具有字符形式的十六进制。我希望遵循“hexa1”的格式,以便将它们解释为数字:
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;
}
最佳答案
我已经通过 Java SE 测试了它,但我还没有将它上传到 Java Card。 Paul Bastian 似乎已经这样做了。
关于十六进制转换的注释在代码中。希望它也展示了一些最佳编程实践:
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
}
}
关于java - 在javacard中将十六进制字符串转换为字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41282249/