【问题标题】:Converting integer list containing binary to hex将包含二进制的整数列表转换为十六进制
【发布时间】:2014-11-18 09:52:46
【问题描述】:

我有一个包含一些二进制值的整数列表

List<Integer> binary = new ArrayList();
for (int i=0; i<8; i++)
{
    bin[i] = pText[i] ^ ivKey[i]; //some binary value is calculated
    binary.add(bin[i]); //the binary list gets updated here
}

for (int i=0; i<myCipher2.size(); i++)
{
    System.out.print(binary.get(i)); //this prints the appended binary as shown in the output
}

打印出来的列表如下:

000001010100001110011101

每 8 位指的是一个十六进制,所以我想要转换后的输出应该给我以下内容

05 43 9 天

如何将列表分成 8 位并将这 8 位转换为十六进制?

【问题讨论】:

  • 通过 goooooooooogling :)
  • 你认为我可能没有尝试过 Kick Buttowski 这种方法?
  • 请解释其中包含一些二进制值。打印ArrayList 永远不会给出该输出。请举一个可重现的例子。
  • 您的列表包含Integer 值,而不是位或字节。 int 用 4 个字节表示。请解释您希望如何以十六进制打印每个Integer(或其对应的int)。你看过Integer.toString(int, int)吗?

标签: java binary hex


【解决方案1】:

首先,你不应该用原始类型声明泛型对象,给你的ArrayList添加一个类型:

List<Integer> binary = new ArrayList<Integer>();

由于与您的问题没有直接关系,您可以read why you should do this here

现在,由于您的列表包含单独的二进制数字,您可以使用StringBuilder 从中构建 8 位二进制字符串。您还可以使用StringBuilder 来构建转换后的十六进制值。每次构建此 8 位字符串时,将其转换为十六进制(实际上是先转换为十进制,然后再转换为十六进制)并将其附加到 StringBuilder,然后构建十六进制字符串。

代码如下:

// ... your program

StringBuilder hexString = new StringBuilder();
StringBuilder eightBits = new StringBuilder();
for(int i = 0; i < binary.size(); i += 8) {                 
    for(int j = i; j < (i + 8) && j < binary.size(); j++) { // read next 8 bits or whatever bits are remaining
        eightBits.append(binary.get(j)); // build 8 bit value
    }
    int decimal = Integer.parseInt(eightBits.toString(), 2); // get decimal value
    hexString.append(Integer.toHexString(decimal) + " "); // add hex value to the hex string and a space for readability 
    eightBits.setLength(0); // reset so we can append the new 8 bits
}
System.out.println(hexString.toString()); // prints "5 43 9d" for the value you gave

注意:此计划是您计划的延续

【讨论】:

  • 整个问题是如何从列表或字符串中一次读取 8 个字符?
  • @KickButtowski 是的,这是这里的主要问题
  • @KickButtowski 好吧,我只是试图回答他的问题,而不是完全重做他的程序。我再次编辑以适合他的代码,程序可以满足他的需要。希望这能让每个人都满意:)
  • @nem 很多次,我都被否决了,因为我不代表任何优化的解决方案,他们的理由是因为操作没有说什么方式,你必须代表最好的方式。正如你所看到的,我没有投票给你,但是当你声称这不是一个正确和好的方法时,问为什么我们应该学习这个是合乎逻辑的?
  • @KickButtowski 我完全理解并同意你的看法。然而,vbenthu 只是在胡闹和学习,他的整个方法似乎非常有效,但他没有展示他的完整代码让我确定如何优化它,也没有询问如何做到这一点的建议.我专门回答他的直接问题,即如何将列表中的 8 个单独的二进制数字转换为十六进制值。你认为我不应该这样做并删除我的答案吗?关于解决这个问题的方法和方法可以进行一个完整的讨论,我只是想帮助他以他的方式解决它......
【解决方案2】:

您可以创建一个二进制字符串并将其转换为十进制,然后再转换为十六进制:

    int[] arr = {0,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,1,0,0,1,1,1,0,1};
    int i = 0;
    while (i < arr.length) {
        String res = "";
        for(int j = 0; j < 8; j++) {
            res += arr[i];
            i++;
        }
        System.out.println(Integer.toHexString(Integer.parseInt(res, 2)));
    }

输出

5
43
9d

【讨论】:

  • 我是这么想的,但我并没有像0-8,9-17那样改变,...?
  • @KickButtowski 您的意思可能是 0-7、8-15、16-23... 我不确定我是否理解您的问题。
【解决方案3】:

所以,这是我的看法...

基本上,这使用List#subList 创建主二进制数组的子列表。每个子列表最多包含 8 个值...

int length = Math.min(8, bits.size());
List<Integer> byteList = bits.subList(0, length);

然后我反转这个列表,你很容易反转for-loop的顺序,这对我来说似乎更简单......

Collections.reverse(byteList);

然后我使用一个简单的for-loop 循环遍历子列表。对于1 的每个位,我只需将其二进制等效项 (Math.pow(2, index)) 添加到结果值中

for (int index = 0; index < byteList.size(); index++) {
    int bit = byteList.get(index);
    if (bit == 1) {
        int pos = (int)Math.pow(2, index);
        value += pos;
    }
}

然后我删除主列表的前 n 个值并继续,直到没有任何剩余...

然后这将打印...

Word = 00000101 = 5; 0x05
Word = 01000011 = 67; 0x43
Word = 10011101 = 157; 0x9d

可运行示例...

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Test100 {

    public static void main(String[] args) {
        List<Integer> bits = new ArrayList<Integer>(25);
        bits.add(0);
        bits.add(0);
        bits.add(0);
        bits.add(0);
        bits.add(0);
        bits.add(1);
        bits.add(0);
        bits.add(1);

        bits.add(0);
        bits.add(1);
        bits.add(0);
        bits.add(0);
        bits.add(0);
        bits.add(0);
        bits.add(1);
        bits.add(1);

        bits.add(1);
        bits.add(0);
        bits.add(0);
        bits.add(1);
        bits.add(1);
        bits.add(1);
        bits.add(0);
        bits.add(1);

        System.out.println();

        while (bits.size() > 0) {

            int length = Math.min(8, bits.size());
            List<Integer> byteList = bits.subList(0, length);
            Collections.reverse(byteList);
            int value = 0;
            StringBuilder binary = new StringBuilder(8);
            for (int index = 0; index < byteList.size(); index++) {
                int bit = byteList.get(index);
                if (bit == 1) {
                    int pos = (int)Math.pow(2, index);
                    value += pos;
                }
                binary.insert(0, bit);
            }

            System.out.println("Word = " + binary + " = " + value + "; 0x" + pad(2, Integer.toHexString(value)));

            int size = Math.max(0, bits.size());
            bits = bits.subList(length, size);

        }
    }

    public static String pad(int length, String value) {
        StringBuilder zeros = new StringBuilder(value);
        while (zeros.length() < length) {
            zeros.insert(0, "0");
        }
        return zeros.toString();
    }

}

【讨论】:

  • @KickButtowski 不知道它是否比其他方法更好或更差,希望能做一些掩蔽,但事实证明这让我头晕目眩……啊,带我回到我在高中的日子......:P
  • 你是个胡闹先生。我一定会学习你的方法。 alsafin 也给出了很好的答案。再次感谢你
猜你喜欢
  • 2012-09-26
  • 1970-01-01
  • 2010-10-16
  • 2012-06-26
  • 2014-04-16
  • 2022-01-06
  • 2016-08-28
相关资源
最近更新 更多