【问题标题】:How to generate a random Unicode string including supplementary characters?如何生成包含补充字符的随机 Unicode 字符串?
【发布时间】:2016-12-12 21:28:44
【问题描述】:

我正在编写一些用于生成随机字符串的代码。结果字符串似乎包含无效的char 组合。具体来说,我发现高代理项后面没有低代理项。

谁能解释为什么会这样?我是否必须明确生成随机低代理来跟随高代理?我认为这不是必需的,因为我使用的是 Character 类的 int 变体。

这是测试代码,在最近的一次运行中产生了以下错误配对:

配对不良:d928 - d863 配对不良:da02 - 7bb6 配对不良:dbbc - d85c 配对不良:dbc6 - d85c
public static void main(String[] args) {
  Random r = new Random();
  StringBuilder builder = new StringBuilder();

  int count = 500;
  while (count > 0) {
    int codePoint = r.nextInt(Character.MAX_CODE_POINT + 1);

    if (!Character.isDefined(codePoint)
        || Character.getType(codePoint) == Character.PRIVATE_USE) {
      continue;
    }

    builder.appendCodePoint(codePoint);
    count--;
  }

  String result = builder.toString();

  // Test the result
  char lastChar = 0;
  for (int i = 0; i < result.length(); i++) {
    char c = result.charAt(i);
    if (Character.isHighSurrogate(lastChar) && !Character.isLowSurrogate(c)) {
      System.out.println(String.format("Bad pairing: %s - %s",
          Integer.toHexString(lastChar), Integer.toHexString(c)));
    }
    lastChar = c;
  }
}

【问题讨论】:

  • Character.isDefined 为代理返回 true。

标签: java unicode surrogate-pairs


【解决方案1】:

可以随机生成高或低代理。如果这导致低代理项,或高代理项后没有低代理项,则生成的字符串无效。解决方案是简单地排除所有代理:

if (!Character.isDefined(codePoint)
    || (codePoint <= Character.MAX_CHAR && Character.isSurrogate((char)codePoint))
    || Character.getType(codePoint) == Character.PRIVATE_USE) {
  continue;
}

或者,它应该只查看从getType返回的类型:

int type = Character.getType(codePoint);
if (type == Character.PRIVATE_USE ||
    type == Character.SURROGATE ||
    type == Character.UNASSIGNED)
    continue;

(从技术上讲,您还可以允许随机生成高代理并添加另一个随机低代理,但这只会创建其他随机代码点 >= 0x10000,而这可能是未定义的或供私人使用的。)

【讨论】:

  • isSurrogate 接受一个字符,而不是一个代码点。我不确定在这个阶段施放是否真的安全。
【解决方案2】:

您需要排除所有个代理孤儿(即高代理和低代理)。

仅供参考,UnicodeData.txt 的下一段摘录显示了代理的代码点间隔:

D800;<Non Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
DB7F;<Non Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
DB80;<Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
DBFF;<Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
DC00;<Low Surrogate, First>;Cs;0;L;;;;;N;;;;;
DFFF;<Low Surrogate, Last>;Cs;0;L;;;;;N;;;;;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    相关资源
    最近更新 更多