[英]How to convert int array to hex string
I want to convert an int
array to a hex string. 我想将一个
int
数组转换为一个十六进制字符串。 I am unsure if I am doing this correctly. 我不确定我是否正确执行此操作。
I create an int[]
in another class and get it with via msg.obj
. 我在另一个类中创建一个
int[]
,并通过 msg.obj
获得它。 I am getting some values in Hex but am unsure if they are correct. 我在十六进制中得到了一些值,但不确定它们是否正确。
int[] readBuf = (int[]) msg.obj; //int array is in another class
StringBuffer output=new StringBuffer();
for (int a:readBuf) {
int val1 = a & 0xff;
output.append(Integer.toHexString(val1));
}
dataView.setText(output);
Assuming I understand your intention, there are two problems with the code: 假设我了解您的意图,那么代码有两个问题:
int val1 = a & 0xff;
You're taking only the last byte of your int. 您只占用int的最后一个字节。 If you want to convert the whole integer, remove the
&0xff
. 如果要转换整个整数,请删除
&0xff
。
You want to makes sure that the output of Integer.toHexString
is always padded with zeroes in front so it's length is always 8 characters (since every byte of the 4 byte long int requres 2 characters). 您要确保
Integer.toHexString
的输出始终在前面填充零,因此其长度始终为8个字符(因为4字节长的int的每个字节都需要2个字符)。 Otherwise both array {1,2,3}
and the array {291}
will give you the same string - 123
. 否则,数组
{1,2,3}
和数组{291}
都将为您提供相同的字符串123
。
here's a quick and dirty working code example 这是一个快速而肮脏的工作代码示例
public static String byteToUnsignedHex(int i) {
String hex = Integer.toHexString(i);
while(hex.length() < 8){
hex = "0" + hex;
}
return hex;
}
public static String intArrToHex(int[] arr) {
StringBuilder builder = new StringBuilder(arr.length * 8);
for (int b : arr) {
builder.append(byteToUnsignedHex(b));
}
return builder.toString();
}
public static void main(String[] args){
System.out.println(intArrToHex(new int[]{1,2,3}));
System.out.println(intArrToHex(new int[]{291}));
System.out.println(intArrToHex(new int[]{0xFFFFFFFF}));
}
Output: 输出:
000000010000000200000003
00000123
ffffffff
@Malt's answer definitely highlights the problem with your code: that it doesn't 0-pad the int
hex values; @Malt的答案肯定突出了您的代码的问题:它不会0-填充
int
十六进制值; and that you mask the int to only take the last 8 bits using a & 0xff
. 并且您将int掩码为使用
a & 0xff
仅占用最后8位。 Your original question implies you are only after the last byte
in each int
, but it really isn't clear. 您最初的问题意味着您仅在每个
int
的最后一个byte
之后,但这确实不清楚。
You say you get results every second from your remote object. 您说您每秒从远程对象获得结果。 On a slow machine with large arrays it is possible that it could take a significant number of milliseconds to convert a long
int[]
to a hex string using your method using your (or rather Malt's corrected version of your) method. 在具有大型数组的慢速计算机上,使用您的方法(或者您的Malt的校正版本)将您的方法将长
int[]
转换为十六进制字符串可能会花费大量的毫秒。
A much faster method would be to get each 4-bit nibble from each int using bit shifting, and get the appropriate hex character from a static hex lookup array ( note this does base-16 encoding, you would get shorter strings from something like base-64 encoding ): 一种更快的方法是使用位移从每个int获取每个4位半字节 ,并从静态十六进制查找数组中获取适当的十六进制字符( 请注意,此操作采用base-16编码,您将从诸如base之类的字符串中获取较短的字符串-64编码 ):
public class AltConverter {
final protected static char[] encoding = "0123456789ABCDEF".toCharArray();
public String convertToString(int[] arr) {
char[] encodedChars = new char[arr.length * 4 * 2];
for (int i = 0; i < arr.length; i++) {
int v = arr[i];
int idx = i * 4 * 2;
for (int j = 0; j < 8; j++) {
encodedChars[idx + j] = encoding[(v >>> ((7-j)*4)) & 0x0F];
}
}
return new String(encodedChars);
}
}
Testing this vs your original method using caliper (microbenchmark results here ) shows this is around 11x faster † (caveat: on my machine). 使用游标卡尺测试此方法与原始方法( 此处为微基准测试结果 )显示,速度大约提高了11倍† (注意:在我的机器上)。 EDIT For anyone interested in running this and comparing the results, there is a gist here with the source code. 编辑对于有兴趣运行此程序并比较结果的任何人, 此处都有源代码的要点 。
Even for a single element array 即使是单个元素数组
The original microbenchmark used Caliper as I happened to be trying it out at the time. 最初的微基准测试使用的是Caliper,因为我当时正尝试使用它。 I have rewritten it to use JMH .
我已将其重写为使用JMH 。 While doing so I found that the results I linked to and copied here originally used an array that was only ever filled with
0
for each int
element. 这样做时,我发现链接到并复制到此处的结果最初使用的数组仅对每个
int
元素填充0
。 This caused the JVM to optimise the AltConverter
code for arrays with length > 1
yielding artificial 10x to 11x improvements in AltConverter
vs SimpleConverter
. 这导致JVM针对长度大于
1
数组优化了AltConverter
代码,从而在AltConverter
和SimpleConverter
获得了10到11倍的人工改进。 JMH and Caliper produce very similar results for both the flawed and corrected benchmark. 对于有缺陷和经过修正的基准测试,JMH和Caliper产生的结果非常相似。 (Updated benchmark project for maven eclipse here ).
( 此处更新了Maven Eclipse的基准测试项目)。
This is around 2x to 4x faster depending on array length ( on my machine™ ). 根据阵列长度的不同( 在我的机器™上 ),速度大约快2到4倍。 The mean runtime results (in ns) are:
平均运行时间结果(以ns为单位)为:
Average run times in nanoseconds Original method: SimpleConverter New method: AltConverter | N | Alt / ns | error / ns | Simple / ns | Error / ns |Speed up | | ---------: | ---------: | ---------: | ----------: | ---------: | -------: | | 1 | 30 | 1 | 61 | 2 |
2.0x | | 100 | 852 | 19 | 3,724 | 99 |
4.4x | | 1000 | 7,517 | 200 | 36,484 | 879 |
4.9x | | 1000,0 | 82,641 | 1,416 | 360,670 | 5,728 |
4.4x | | 1000,00 | 1,014,612 | 241,089 | 4,006,940 | 91,870 |
3.9x | | 1000,000 | 9,929,510 | 174,006 | 41,077,214 | 1,181,322 |
4.1x | | 1000,000,0 | 182,698,229 | 16,571,654 | 432,730,259 | 13,310,797 |
2.4x |
† Disclaimer: Micro-benchmarking is dangerous to rely on as an indication of performance in a real world app, but caliper is a good benchmarking framework, jmh is imho better. † 免责声明:依靠微基准测试作为现实应用程序性能的指标很危险,但是caliper是一个很好的基准测试框架,jmh更好。 A performance difference of
10x 4x, with very small standard deviation, in caliper a good t-test result is enough to indicate a good performance increase even inside a more complex application . 在卡尺上 ,具有非常小的标准偏差的10x 4x的性能差异,即使在更复杂的应用程序内,良好的t检验结果也足以表明性能得到了很好的提高 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.