简体   繁体   English

如何将int数组转换为十六进制字符串

[英]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: 假设我了解您的意图,那么代码有两个问题:

  1. 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

  2. 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代码,从而在AltConverterSimpleConverter获得了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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM