【问题标题】:Java UTF-8 String does not match C# UTF-8 StringJava UTF-8 字符串与 C# UTF-8 字符串不匹配
【发布时间】:2023-03-27 15:02:01
【问题描述】:

我有两个字节数组来自(在 C# 和 Java 中)一个字符串。当我转换数组时,结果不匹配。这可能是什么原因?这个问题不是一成不变的。有时它会产生相同的结果。

 C#:
[0] 148 
[1] 70  
[2] 38  
[3] 173 
[4] 249 
[5] 227 
[6] 183 
[7] 106 
[8] 57  
[9] 25  
[10] 181    
[11] 13 
[12] 192    
[13] 176    
[14] 128    
[15] 164    

   Java :


    0 = -108 
    1 = 70
    2 = 38
    3 = -83
    4 = -7
    5 = -29
    6 = -73
    7 = 106
    8 = 57
    9 = 25
    10 = -75
    11 = 13
    12 = -64
    13 = -80
    14 = -128
    15 = -92

C# 结果:“F&���j9�\r����

Java 结果:�F&���j9�0��

编辑:

转换器代码;

C# -
String result = UTF8Encoding.UTF8.GetString(byteArray);

Java: 
String result = new String(byteArray, "UTF-8");

*Edit-2 : 真正的转换。

C# :
        [0] 239 
        [1] 195 
        [2] 40  
        [3] 19  
        [4] 185 
        [5] 36  
        [6] 77  
        [7] 132 
        [8] 182 
        [9] 122 
        [11]    173 
        [12]    12  
        [13]    191 
        [14]    100 
        [15]    118 
Java :

0 = -17
1 = -61
2 = 40
3 = 19
4 = -71
5 = 36
6 = 77
7 = -124
8 = -74
9 = 122
10 = -70
11 = -83
12 = 12
13 = -65
14 = 100
15 = 118

C# 结果:��(�$M��z���dv Java 结果:��(�$M��z���dv*

【问题讨论】:

  • 也许一些代码可能会有所帮助...?
  • 这些是相同的值,只是您似乎以不同的格式显示它们。它们在 C# 中未签名(范围 0 / 255)并在 Java 中签名(范围 -128 / +127)
  • 请提供一个minimal reproducible example,它显示了结果字符串的 UTF-16 代码单元。还要指出字节的来源。如果它们不是以 UTF-8 编码的文本开头,则不应尝试将它们解码为 UTF-8。
  • @JonSkeet java : value.getBytes(Charset.forName("UTF-8")); C# : UTF8Encoding 编码器 = new UTF8Encoding();编码器.GetBytes(值); ..而且我无法更改 C# 代码。它在服务器中
  • 所以你应该知道原始字符串是什么,并且你应该能够说出哪个解码出错了。请提供minimal reproducible example,这样会更容易为您提供帮助。

标签: java c# utf-8


【解决方案1】:

我假设您上面显示的输出是与 C# 和 Java 中的字符串对应的字节数组。

byte in Java is a signed type (between -128 and 127),它解释了某些字节的负值。

看起来 Java 的所有正值都与对应的 C# 值匹配,而只有 Java 中的负值与对应的 C# 值不匹配。原因是C# bytes are unsigned (between 0 and 255)

如果您打印与 Java 字节对应的无符号值,您应该得到与 C# 中相同的输出:

for (byte b : byteArray)
    System.out.println(b & 0xff);

【讨论】:

  • 好的,但是对于某些数组(Java:有符号,C#:无符号),它可以在两者中产生相同的结果。
  • @fatihbolat 当然,如果所有字节恰好在 0 到 127 之间,Java 和 C# 都会产生相同的输出。
  • stackoverflow.com/a/45027202/8287517@eran。 @HB 是对的。所以我希望产生相同的字符串。但是,在某些情况下并非如此。
  • @fatihbolat 你是如何产生这些字节数组的?
  • java : value.getBytes(Charset.forName("UTF-8")); C# : UTF8Encoding 编码器 = new UTF8Encoding();编码器.GetBytes(值); @Eran
【解决方案2】:

-108148 的二进制值都相同。

在java中,如果你将字符串转换为字节数组,那么char grater的值然后127被转换为负值。

看windows计算器的值148:

-108 的值相同:

现在丢弃前 8 位之后的位,即1001 0100,两者相同。 注意:需要丢弃,因为字节长度是8位。

【讨论】:

    猜你喜欢
    • 2017-03-04
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2016-05-31
    • 2023-03-18
    相关资源
    最近更新 更多