【问题标题】:ASCII code equivalent of unicode character in JavaJava中Unicode字符的ASCII码等价物
【发布时间】:2013-10-03 05:23:15
【问题描述】:

我们在将以下逻辑从 C++ 移植到 Java 时遇到问题。 Java 方法应该返回与 C++ 函数相同的值。如果 keyValue 包含非 ASCII 字符,则逻辑失败。

C++函数如下,

   int CMyClass::KeyToId( const char *keyValue ) {

    int sum = 0, len = strlen( keyValue );

       // Get a sum based on the characters in the string.
       // Each character contributes + <ASCII-value> * 11.
       for( int i = 0; i < len; i++ )   sum += keyValue[i] * 11;
       // Modulo the result to get a value in the standard range.
       return sum;  
   }

在第 2 行,keyValue[i] 被转换为 8 字节的 ascii 码。

Java 的确切端口如下所示:

private int keyToId(String keyValue) {
     int sum = 0, len =  keyValue.length();

        // Get a sum based on the characters in the string.
        // Each character contributes + <ASCII-value> * 11.

        for( int i = 0; i < len; i++ )   
            sum += keyValue.charAt(i) * 11;
    return sum;
}

在 Java 中,字符 keyValue.charAt(i) 被转换为“unicode”值。我想不出一种简单的方法将其转换为等效的 ASCII 码。 C++ 应用程序是非 unicode 应用程序。请假设,我们无法更改 C++ 逻辑。

更多输入: 我正在用俄语运行应用程序。对于 красный 的输入,C++ 应用程序返回 -1452。我想从 Java 代码中获得相同的值。

【问题讨论】:

  • 如果您在 Windows 上运行,代码页为 1251,字符串 красный 应编码为 [-22, -16, -32, -15, -19, -5, -23] 和您显示的 C++ 代码应计算 -1452。您可以手动验证。如果它真的返回 -300,那么代码必须做的事情比你所展示的要多。
  • 结果取决于编码,UTF-8 会给出另一个结果。主要问题是 ASCII(一个美国标准)涵盖俄语的错误假设。
  • @Joni -1452 是正确的结果。分享前排除了部分代码,忘记重新计算结果。
  • "在 Java 中,字符 keyValue.charAt(i) 被转换为 "unicode" 值。"不,它返回 UTF-16 代码单元值,仅当 Unicode 代码点在 [U+0000, U+FFFF] 范围内时,它才会与 Unicode 代码点值相同。如果 UTF-16 代码单元值在 [U+D800, U+DCFF] 范围内,那么您有一个代理代码点,实际 Unicode 代码点值在 [U+10000, U+10FFFF] 范围内并且不适合 Java 2 字节 char

标签: java c++ unicode localization ascii


【解决方案1】:

C++ 程序使用平台的默认编码来表示char 数据类型中的字符。要在 Java 中做同样的事情,您必须使用 Java 的等效 byte 数据类型,并在计算之前转换字符串:

byte[] bytes = keyValue.getBytes();
for (byte b: bytes) sum += 11*b;

如果还是不行的话,

  • 在你的C++程序中检查char的符号:大多数编译器默认使用有符号字符,这与Java的字节一致。如果您使用无符号字符,则代码需要进行调整。
  • 首先检查 Java 程序是否正确读取字符串。一种方法是打印字节;给定красный,你应该得到[-22, -16, -32, -15, -19, -5, -23]

    System.out.println(java.util.Arrays.toString(bytes));
    

【讨论】:

  • 在这种情况下也有签名,否则你不会得到-300的结果。
  • 好的,你的第二点提供了一些线索。我在字节数组中得到这个:[63、63、63、63、63、63、63]。我正在检查它..
  • 此文本是否来自文件?可能程序没有正确读取文件。 ASCII 63 是问号,它被用来替代无法在目标编码中表示的字符。
  • 我正在使用从 Eclipse -> Debug -> Arguments 传递的文本进行测试。它以某种方式在中途损坏了文本
【解决方案2】:

尝试将 Java 字符截断为 1 个字节

 sum += (0xFF & keyValue.charAt(i)) * 11;

【讨论】:

    【解决方案3】:

    Charset.forName("US-ASCII").encode(keyValue).toArray()

    给你一个byte[] ASCII 码数组,然后你可以像在 C++ 中一样操作。

    【讨论】:

    • 你是说ByteBuffer的array()方法吗?抱歉,没用。
    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多