Java 使用不同编码时,两个不同的字符串是否具有相同的字节序列?

Java 使用不同编码时,两个不同的字符串是否具有相同的字节序列?,java,encoding,character-encoding,hash,Java,Encoding,Character Encoding,Hash,使用不同编码时,两个不同的字符串是否具有相同的字节序列? i、 e.当使用两种不同编码进行编码时,下面示例中的一些“字符串一”和“字符串二” (Cp1252和UTF-8只是示例)是否会导致测试通过 import java.io.UnsupportedEncodingException; import java.util.Arrays; import org.junit.Assert; import org.junit.Test; public class EncodingTest {

使用不同编码时,两个不同的字符串是否具有相同的字节序列? i、 e.当使用两种不同编码进行编码时,下面示例中的一些“字符串一”和“字符串二” (Cp1252和UTF-8只是示例)是否会导致测试通过

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

import org.junit.Assert;
import org.junit.Test;

public class EncodingTest {
    @Test
    public void test() throws UnsupportedEncodingException {
        final byte[] sequence1 = "string one".getBytes("Cp1252");
        final byte[] sequence2 = "string two".getBytes("UTF-8");
        Assert.assertTrue(Arrays.equals(sequence1, sequence2));
    }
}
我的代码中的一个bug会散列由JVM默认编码的字符串生成的字节序列,我需要验证当代码使用不同的字符串和不同的JVM文件编码运行时(例如,在Windows和Linux上运行时可能会发生这种情况),是否会导致散列冲突

由于编码是字节序列和字符之间的映射,我认为可能有一些字符串和编码通过了上述测试。但是我只是想知道是否有一些众所周知的例子或者一些好的理由来解释为什么我不应该依赖哈希冲突不会发生

谢谢


PS:这仅适用于JDK1.6支持的编码,而不是某些虚构的编码。

这里有一个简单的编码:大多数代码页和UTF-8共享ASCII编码(0x00=0x7F)。如果您的文本是纯英语,则很有可能是ASCII格式的——无论声明的编码是什么,因为它主要使用普通的非重音字符。

如果源字符串采用支持多字节字符的编码,而目标编码不支持多字节字符,由于多字节字符需要映射到单字节字符集,因此可能会发生冲突,这似乎是合理的


例如,如果输入字符串是用中文编写的,并且目标字符集是US-ASCII,那么许多汉字肯定会映射到相同的US-ASCII表示形式。

是的,至少对于不同长度的字符串是可能的

字符串
“\u2020”
(或
“†”
)在UTF-16中编码为
0x20,0x20
。这也是用ASCII编码的
“\x20\x20”
(由两个ASCII空格组成的字符串)

当然,在语言中不经常出现[=^ ^=],但一些标准[非拉丁]字母表可以生成类似的字节序列,映射到标准(非控制字符)ASCII编码。。如果对控制字符的限制放宽,则更多


更有趣的是,如果两个相似的“真实”字符串(例如,相同的长度和“合理的数据”)可以映射到具有不同编码的相同字节序列上,那么这段代码将最终生成一个示例:

    while(true){
        Random r = new Random();
        byte[] bytes = new byte[4];
        r.nextBytes(bytes);
        try{
            String raw = Arrays.toString(bytes);
            String utf8 = new String(bytes, "UTF-8");
            String latin1 = new String(bytes, "ISO-LATIN-1");
            System.out.println(raw + " is " + utf8 + " or " + latin1);
            break;
        }catch(Exception e){}
    }

对。举一个简单的例子,编码为ISO-8859-1的字符串“.”(倒惊叹号)和编码为ISO-8859-2的字符串“Ą”(大写字母a,带ogoned)都成为单字节序列A1(十六进制)。在使用将字符映射到单个字节的非常简单的编码时,这种情况或多或少会发生;否则它们就不会有不同的编码。当涉及到更复杂的编码方案时,这种情况肯定也会发生。

通常使用“默认编码”。。怀疑。注意,这个问题与一些答案的回答相反;这不是两个编码不同的相同字符串是否可以生成相同的字节序列,而是询问两个编码不同的字符串是否可以生成相同的字节序列。(更具体地说,如果存在此类冲突的“已知情况”)为什么哈希冲突很重要?散列代码不必是唯一的。您确实意识到,除非您生活在一个最多有40亿个可能字符串的世界中,否则根据定义,将存在散列冲突。这如何导致两个不同的输入字符串以getBytes()中相同的字节结束?