在不实际编码的情况下以Java String的UTF-8计算长度

特雷弗·罗宾逊(Trevor Robinson):

有谁知道标准Java库(任何版本)是否提供一种无需实际生成编码输出即可计算字符串(在这种情况下为UTF-8)二进制编码长度的方法?换句话说,我正在寻找一种等效的方法:

"some really long string".getBytes("UTF-8").length

我需要为可能很长的序列化消息计算长度前缀。

麦克道尔:

这是一个基于UTF-8规范的实现

public class Utf8LenCounter {
  public static int length(CharSequence sequence) {
    int count = 0;
    for (int i = 0, len = sequence.length(); i < len; i++) {
      char ch = sequence.charAt(i);
      if (ch <= 0x7F) {
        count++;
      } else if (ch <= 0x7FF) {
        count += 2;
      } else if (Character.isHighSurrogate(ch)) {
        count += 4;
        ++i;
      } else {
        count += 3;
      }
    }
    return count;
  }
}

此实现不能容忍格式错误的字符串。

这是用于验证的JUnit 4测试:

public class LenCounterTest {
  @Test public void testUtf8Len() {
    Charset utf8 = Charset.forName("UTF-8");
    AllCodepointsIterator iterator = new AllCodepointsIterator();
    while (iterator.hasNext()) {
      String test = new String(Character.toChars(iterator.next()));
      Assert.assertEquals(test.getBytes(utf8).length,
                          Utf8LenCounter.length(test));
    }
  }

  private static class AllCodepointsIterator {
    private static final int MAX = 0x10FFFF; //see http://unicode.org/glossary/
    private static final int SURROGATE_FIRST = 0xD800;
    private static final int SURROGATE_LAST = 0xDFFF;
    private int codepoint = 0;
    public boolean hasNext() { return codepoint < MAX; }
    public int next() {
      int ret = codepoint;
      codepoint = next(codepoint);
      return ret;
    }
    private int next(int codepoint) {
      while (codepoint++ < MAX) {
        if (codepoint == SURROGATE_FIRST) { codepoint = SURROGATE_LAST + 1; }
        if (!Character.isDefined(codepoint)) { continue; }
        return codepoint;
      }
      return MAX;
    }
  }
}

请原谅紧凑格式。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Java中第一个参数的计算长度

如何在不实际滚动的情况下确定滚动方向

Java对String的内部表示是什么?修改过的UTF-8?UTF-16?

DOMImplementationLS在Java中以UTF-8序列化为String

如何在不实际序列化对象的情况下估计Java中对象的序列化大小?

如何在不实际运行代码的情况下知道实现Comparable <>的类的排序顺序?

在调用string.length时string.length是否计算长度

如何在不实际运行“ vagrant ssh”的情况下ssh变成无业游民?

如何在不实际使用<form>的情况下使用引导表单布局?

如何在不实际显示地图的情况下拍摄Google地图快照

Elixir:String Force编码UTF-8

在不使用String或Charset的情况下,将字符数组从UTF-8转换为字节数组

如何在不通过ruby的UTF-8的情况下将编码从ASCII-8BIT转换为另一种编码?

是否可以在不实际打印的情况下将打印布局显示为html页面?

如何在不实际执行HTTP DELETE操作的情况下对其进行建模

如何在不实际聚焦元素的情况下触发聚焦处理程序?

Git:在不实际下载数据的情况下克隆/初始化存储库?

std :: string和UTF-8编码的unicode

如何在不实际合并的情况下“合并” git分支

在不使用@page指令的情况下,将所有JSP的默认编码设置为UTF-8。

在不使用BOM编码的情况下,使用UTF-8在WinSCP中创建新文件

在不实际运行脚本的情况下检查VBScript的语法错误

如何在不实际运行的情况下测试可执行文件?

如何在不实际下载资源的情况下获得资源的大小?

具有实体的List <String>编码为UTF-8

如何在不实际渲染我的网页的情况下渲染 404?

是否可以在不实际使用“null”的情况下创建“null”值?

我可以在不实际关闭小部件的情况下使用 Dismissible 吗?

Pine 脚本 - 计算长度变化指标