【问题标题】:Java - What is the proper way to convert a UTF-8 String to binary?Java - 将 UTF-8 字符串转换为二进制的正确方法是什么?
【发布时间】:2020-04-06 11:37:04
【问题描述】:

我正在使用此代码将 UTF-8 String 转换为二进制:

public String toBinary(String str) {
    byte[] buf = str.getBytes(StandardCharsets.UTF_8);
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < buf.length; i++) {
        int ch = (int) buf[i];
        String binary = Integer.toBinaryString(ch);
        result.append(("00000000" + binary).substring(binary.length()));
        result.append(' ');
    }
    return result.toString().trim();
}

在我使用这段代码之前:

private String toBinary2(String str) {
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < str.length(); i++) {
        int ch = (int) str.charAt(i);
        String binary = Integer.toBinaryString(ch);
        if (ch<256)
           result.append(("00000000" + binary).substring(binary.length()));
        else {
           binary = ("0000000000000000" + binary).substring(binary.length());
           result.append(binary.substring(0, 8));
           result.append(' ');
           result.append(binary.substring(8));
        }
        result.append(' ');
    }
    return result.toString().trim();
}

这两种方法可以返回不同的结果;例如:

toBinary("è") = "11000011 10101000"
toBinary2("è") = "11101000"

我认为这是因为 è 的字节是负数,而对应的 char 不是(因为 char 是一个 2 字节的无符号整数)。
我想知道的是:这两种方法中哪一种是正确的,为什么?
提前致谢。

【问题讨论】:

  • 首先,您需要了解 Java 中没有“UTF-8 字符串”之类的东西。所有字符串(至少在概念上)都是 UTF-16 代码单元的序列。您的 toBinary2 方法根本没有执行任何 UTF-8 编码,这就是它不正确的原因。您需要将代码的两部分分开,至少在您的脑海中:1)将字符串转换为二进制数据(byte[]),例如与getBytes。 2) 将该二进制数据转换为文本二进制表示。

标签: java utf-8 binary


【解决方案1】:

每当您想将文本转换为二进制数据(或转换为表示二进制数据的文本,就像您在此处所做的那样)时,您必须使用某种编码

您的 toBinary 使用 UTF-8 进行编码。

您的 toBinary2 使用了非标准编码:它将每个 UTF-16 代码点 *

tl;dr toBinary 似乎是正确的,toBinary2 将产生无法唯一解码回原始字符串的输出。

* 您可能想知道提到 UTF-16 是从哪里来的:这是因为 Java 中的所有 String 对象都隐式编码为 UTF-16。因此,如果您使用charAt,您将获得 UTF-16 代码点(恰好等于适合基本多语言平面的所有字符的 Unicode 代码号)。

【讨论】:

    【解决方案2】:

    这段代码 sn-p 可能会有所帮助。

    String s = "Some String";
    byte[] bytes = s.getBytes();
    StringBuilder binary = new StringBuilder();
    for(byte b:bytes){
        int val =b;
        for(int i=;i<=s.length;i++){
            binary.append((val & 128) == 0 ? 0 : 1);
            val<<=1;
        }
    }
    System.out.println(" "+s+ "to binary" +binary);
    

    【讨论】:

      猜你喜欢
      • 2017-06-14
      • 2016-11-12
      • 2011-08-14
      • 2020-10-26
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 2016-07-01
      相关资源
      最近更新 更多