4

欢迎unsafe登陆。

我正在对一个遗留库进行 P/Invoke,它以未知长度的非托管字节缓冲区的形式为我提供了一个以 0 结尾的 C 样式字符串,该缓冲区可以是 ASCIIUTF-16,但没有给出任何指示- 除了字节流本身...

现在我有一个糟糕的方案,基于检查单字节和双 0 字节,来决定是否应该创建一个托管String的 fromChar*SByte*. 对于每个高于U+00FF.

这就是我所拥有的:

  • 非托管字节缓冲区的地址。
  • 非托管字节缓冲区的长度未知。
  • 非托管字节缓冲区是一个以 0 结尾的 ASCII C 样式字符串或一个以 0 结尾的 UTF-16 C 样式字符串。

这就是我要的:

  • 从非托管字节缓冲区创建正确String的托管字节缓冲区,无论是 ASCII 还是 UTF-16。

这个问题一般可以解决吗?

4

3 回答 3

4

我不认为这可以100%解决。如果缓冲区包含 6c 34 00 00 ("l4"),那是水的中文符号,还是只是一个 ASCII 小写 L 和 4?但是应该可以根据特定的字符串“大部分时间”猜对。

UTF-16 是小端还是(可能)大端?

最大的风险是缓冲区溢出。例如,如果缓冲区以 00 开头,那是零长度的 ASCII 字符串,还是我们应该尝试准备更多的缓冲区,将其解释为 UTF-16BE?

于 2010-07-01T09:16:34.220 回答
2

这个问题一般可以解决吗?

不。

如果您知道字符串的长度(并且它是偶数),您可以通过 00 字节填充 ISO-8859-1 字符来识别 UTF-16。(即使是非拉丁字母语言仍然会大量使用 ASCII 空格和换行符。)

但是,如果您依赖空终止,那将无济于事。如果您查找 00 00,您可以间接匹配恰好位于空终止符之后的 00 字节。更糟糕的是,如果 ASCII 字符串不是以双空结尾的,那么您将直接运行到字符串的末尾。

于 2010-07-18T01:48:06.167 回答
0

一种向基于检查单字节和双 0 字节的朴素编码检测方案添加启发式方法的方法:

  1. 假设来自遗留库的编组“上下文”由一个或多个字符串组成。
  2. 如果这种上下文中的一个字符串很可能是 UTF-16,那么该上下文中的所有其他字符串也是 UTF-16。
  3. 因此,一旦找到具有“足够高”确定性的 UTF-16 字符串,就将所有其他检测结果偏向“可能是 UTF-16”。
  4. 如果发现“可能不是 UTF-16”的字符串是“肯定不是 UTF-8”的字符串,那么也不能是 ASCII,所以设置为 UTF-16。

这将提供更高的准确创建托管Strings 的比率。

于 2010-06-29T13:01:37.233 回答