在 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
}
}
我正在尝试开发 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
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
}
}