在 java 中将整数转换为字节十六进制

Converting integer to byte hex in java

我正在尝试开发 java 卡片应用程序。将有一个动态输入字符串,它将在字节数组中包含一个 phone 数字,例如:

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

我希望将此数组更改为以下数组:

byte[] changed num = {(byte)0x0C, (byte)0x91, (byte)0x19, (byte)0x21, (byte)0x43, (byte)0x65, (byte)0x87, (byte)0x59}

前三个字节始终相同,其余 5 个字节将从传入数组更新。

我试过以下方法:

public static void main(String args[]){
byte[] number =new byte[] {1,2,3,4,5,6,7,8,9,5};

byte[] changednum = new byte[8];

changednum[0] = (byte)0x0C;
changednum[1] = (byte)0x91;
changednum[2] = (byte)0x19;
changednum[3] = (byte)0x(number[0] + number[1]*10);
changednum[4] = (byte)0x(number[2] + number[3]*10);
changednum[5] = (byte)0x(number[4] + number[5]*10);
changednum[6] = (byte)0x(number[6] + number[7]*10);
changednum[7] = (byte)0x(number[8] + number[9]*10);

System.out.println(Arrays.toString(changednum));

}
} 

但是最后 5 个值没有被转换为字节值


s.

您可以使用 Integer.toHexString 方法进行转换, 您需要仔细注意将显式整数转换为 -128 到 127

之间的字节 will truncate its value in a range
 final int f = -2211;
 System.out.println(f);
 System.out.println((byte) f);
 System.out.println(Integer.toHexString((byte) f));

这一行

changednum[3] = (byte)0x(number[0] + number[1]*10);

可以通过一组复杂的字符串操作来完成,多么简单的数学运算就能完成你想要的事情。

changednum[3] = (byte)(number[0] + number[1]*16);

*16 是必需的,因为您似乎假设数字是十六进制的。

你可以使用循环

for (int i = 0; i < 4; i++)
    changednum[i+3] = (byte)(number[i*2] + number[i*2+1]*16);

或使用 += 来避免转换

for (int i = 0; i < 4; i++)
    changednum[i+3] += number[i*2] + number[i*2+1] * 16;

或者你可以写

for (int i = 0; i < 4; i++)
    changednum[i+3] += number[i*2] + (number[i*2+1] << 4);

虽然在Java的标准版中并不是很重要,但在Java卡中性能往往是至关重要的。由于按位运算符,此解决方案比接受的答案稍快,并且它是有效的 Java 没有 32 位整数的卡代码:

for (short i = 3, j = 0; i < 7; i++, j += 2) {
    changednum[i] = (byte) ((number[j+1] << 4) | (number[j] & 0x0F));
}

在我看来,其他答案缺乏可读性。

此解决方案使用单独的方法和 ByteBuffer 来使这些方法在不传递偏移量和其他管道的情况下工作。它有奇怪的东西,比如常量和经过深思熟虑的标识符、异常、JavaDoc 和可维护性书中的其他可怕概念。

package nl.owlstead.Whosebug;

import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;

/**
 * Helper class to create telephone numbers with headers for Java card using
 * reverse packed BCD format.
 * 
 * @param buffer
 *            a buffer with enough space for the 3 byte header
 */
public final class OverlyDesignedTelephoneNumberHelper {

    private static final int TELEPHONE_NUMBER_SIZE = 10;
    private static final int NIBBLE_SIZE = 4;
    private static final byte[] HEADER = { (byte) 0x0C, (byte) 0x91,
            (byte) 0x19 };

    /**
     * Adds the header for the telephone number to the given buffer.
     * 
     * @param buffer
     *            a buffer with enough space for the 3 byte header
     * @throws NullPointerException
     *             if the buffer is null
     * @throws BufferOverflowException
     *             if the buffer doesn't have enough space for the header
     */
    private static void addTelephoneNumberHeader(final ByteBuffer buffer) {
        buffer.put(HEADER);
    }

    /**
     * Adds the telephone number to the given buffer.
     * 
     * @param buffer
     *            a buffer with enough space for the 3 byte header
     * @param number
     *            the number in BCD format, should be 10 bytes in size
     * @throws IllegalArgumentException
     *             if the number is null or doesn't contain 10 BCD digits
     * @throws NullPointerException
     *             if the buffer is null
     * @throws BufferOverflowException
     *             if the buffer doesn't have enough space for the telephone
     *             number
     */
    private static void addTelephoneNumber(final ByteBuffer buffer,
            final byte[] number) {
        if (number == null || number.length != TELEPHONE_NUMBER_SIZE) {
            throw new IllegalArgumentException("Expecting 10 digit number");
        }

        for (int i = 0; i < number.length; i += 2) {
            final byte lowDigit = number[i];
            validateUnpackedBCDDigit(lowDigit);
            final byte highDigit = number[i + 1];
            validateUnpackedBCDDigit(highDigit);

            buffer.put((byte) ((highDigit << NIBBLE_SIZE) | lowDigit));
        }
    }

    /**
     * Tests if the given unpacked BCD digit is within range.
     * 
     * @param b
     *            the byte to test
     * @throws IllegalArgumentException
     *             if it isn't
     */
    private static void validateUnpackedBCDDigit(final byte b) {
        if (b < 0 || b > 9) {
            throw new IllegalArgumentException(
                    "Telefonenumber isn't all bytes representing digits in BCD");
        }
    }

    public static void main(final String... args) {
        final byte[] number = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 5 };

        final ByteBuffer buf = ByteBuffer.allocate(HEADER.length
                + TELEPHONE_NUMBER_SIZE);
        addTelephoneNumberHeader(buf);
        addTelephoneNumber(buf, number);
        buf.flip();
        while (buf.hasRemaining()) {
            System.out.printf("%02X", buf.get());
        }
        System.out.println();
    }

    private OverlyDesignedTelephoneNumberHelper() {
        // avoid instantiation
    }
}