3

使用不同编码编码的两个不同字符串可以具有相同的字节序列吗?即以下示例中的一些“字符串一”和“字符串二”在使用两种不同的编码(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));
    }
}

我的代码中的一个错误对使用 JVM 的默认编码的字符串生成的字节序列进行哈希处理,我需要验证当代码使用不同的字符串和不同的 JVM 文件编码运行时是否会导致哈希冲突(在 Windows 和 Linux 上运行时可能会发生这种情况例如)。

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

谢谢

PS:这仅适用于 JDK 1.6 支持的编码,而不是某些编造的编码。

4

5 回答 5

2

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

于 2012-07-20T04:47:11.490 回答
1

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

字符串"\u2020"(或"†")被编码为0x20,0x20UTF-16。这也是"\x20\x20"(由两个 ASCII 空格组成的字符串)以 ASCII 编码的内容。

当然,匕首,在语言中并不经常出现 [=^_^=],但是一些标准的 [非拉丁] 字母可以生成类似的字节序列,映射到标准(非控制字符)ASCII encoding .. 如果放宽控制字符的限制,还有更多。

找到两个相似的“现实”字符串(例如相同长度和“敏感数据”)可以映射到具有不同编码的相同字节序列的情况会更有趣。

于 2012-07-20T02:10:44.987 回答
1

此代码最终应生成一个示例:

    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){}
    }
于 2012-07-20T02:13:01.447 回答
1

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

于 2012-07-20T01:40:28.763 回答
1

如果源字符串的编码支持多字节字符,而目标编码不支持多字节字符,那么发生冲突似乎是合理的,因为多字节字符需要映射到单个字符字节字符集。

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

于 2012-07-20T01:43:14.487 回答