【问题标题】:convert ASCII into Hex将 ASCII 转换为十六进制
【发布时间】:2017-08-02 07:30:11
【问题描述】:

我有一个 Gui,我想将 ASCII 转换为十六进制,但它打印我的是 fffff84 而不是 84。这只发生在 ä、ö、ü。出了什么问题?

示例输入:

ä

输出:

ffffff84

我的代码:

asciihex.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            output6.setText("");
            String hexadecimal2 = input4.getText().replace("\n", "");
            byte[] chars;
            try {
                chars = hexadecimal2.getBytes("CP850");
                StringBuffer hexa = new StringBuffer();
                for(int i = 0;i<chars.length;i++){
                    hexa.append(Integer.toHexString((int) chars[i]));
                }
                output6.append(hexa.toString());                    
            } catch (UnsupportedEncodingException e1) {

                e1.printStackTrace();
            }
        }
    });

【问题讨论】:

  • ASCII 实际上是一个 7 位编码方案(值从 0127 (0x7f))。 0x84 可能是 extended ASCII 的一部分,但不是标准的。如果存储在有符号字节中(使用two's complement),它也是一个数。因为它是负数,所以如果将有符号字节存储在更大的有符号整数类型中,它会得到符号扩展。
  • CP850 不是 ASCII
  • Code page 850 不是ASCII。而ä 不是 ASCII 字符。
  • @saka1029 为什么不是 ASCII?
  • @Starlight:出于同样的原因,西班牙语不是英语,尽管有一些共同点。只是不是。有关详细信息,请参阅我上面评论中的链接。

标签: java hex ascii data-conversion


【解决方案1】:

Code page 850 不是ASCIIä 不是 ASCII 字符。您的其他无法正常工作的字符示例也没有。

发生的情况是这些字符的值(作为字节)是负数,因为byte 是 Java 中的有符号类型。 (例如,ä 是 -124。)二进制补码十六进制中的 -124 作为 int 是 0xFFFFF84。您可以通过将其添加到 256 来获得它的未签名版本,以获得 132 (0x84)。然后你转换为十六进制就可以了。

【讨论】:

  • 为什么这不是 ASCII 码?当我将十六进制转换为 ASCII 时,我使用 E4 并打印 ä。那么,如果我想将 Ascii 转换为 Hex,为什么不这样做呢?
  • 另一种将byte 转换为int 忽略符号的方法:hexa.append(Integer.toHexString((int) chars[i] &amp; 0xFF));
  • @Starlight 请阅读维基百科上的 ASCII 文章,只需点击一下即可...
  • @T.J. Crowder 如何将 0xFFFFF84 添加到 256?
  • @Starlight:嗯...chars[0] &lt; 0 ? chars[0] + 256 : chars[0].
【解决方案2】:

您必须将字节值无符号转换转换为int,例如

hexa.append(Integer.toHexString((int) chars[i] & 0xFF));

或(Java 8)

hexa.append(Integer.toHexString(Byte.toUnsignedInt(chars[i])));

【讨论】:

    【解决方案3】:

    首先,“ä”的十六进制值不是0x84,而是0x7B。 如需检查所有十六进制值,请参阅标准“ETSI TS 123 038 V14.0.0 (2017-04)”。

    现在对于编码部分,我已经创建了一个函数,它接受任何 ASCII 字符并根据给定标准返回其十六进制值。由于我不想发布该代码,因为这将是勺子喂食,而是我想指导您编写自己的代码。

    步骤: 1.首先参考给定的文档并理解给定的字符表。 2. 创建一个列表,其中包含根据索引值在表中给出的所有字符。 3. 制作一个函数来提取给定字符的索引位置并制作实际的十六进制数。请记住为扩展字符集编写额外的功能。

    希望这会对您有所帮助。 :-)

    【讨论】:

    • “首先,“ä”的十六进制值不是 0x84,而是 0x7B” 不在代码页 850 中。在 CP850 中是 0x84。在其他代码页中,它将具有其他值。它是 Unicode 格式的 U-00E4
    • 嗨 T.J.感谢您的评论。现在我要提到的一件事是,如果我们谈论的是十六进制值,那么我们必须参考 ETSI TS 123 038 V14.0.0 (2017-04),因为它是字符十六进制值的标准。我只是在谈论一个通用标准,根据这个标准,值是 0x7B。请随意阅读本标准。 :-)
    • 关于蜂窝数据传输的标准在此完全适用。同样:表示字符的数值因代码页/文本编码而异。 OP 使用数值,呈现为十六进制。您可能会发现 this article 对于相同字符的不同编码很有用。
    • 嗨 T.J.感谢您提出观点,但我理解正确。我每天都在处理十六进制-文本-十六进制转换。 OP 已询问“我想将 ASCII 转换为十六进制”。有不同的方法来转换相同的,但它们不能是标准的。根据给定标准,建议转换为 0x84 是不正确的。我建议了处理十六进制值的标准方法。请告诉我代码页转换的标准,这对我来说将是一个新的学习。 :-)
    • 同样,this article 可能会有用。可能还有this one
    猜你喜欢
    • 1970-01-01
    • 2017-08-28
    • 2017-10-13
    • 2016-09-27
    • 2011-11-21
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多