我是靠谱客的博主 爱听歌悟空,最近开发中收集的这篇文章主要介绍hello, unicode surrogate版权UnicodeJavaGoWindows C相关文章参考,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

  • 版权
  • Unicode
  • Java
  • Go
  • Windows C
  • 相关文章
  • 参考

版权

本文为原创, 遵循 CC 4.0 BY-SA 版权协议, 转载需注明出处: https://blog.csdn.net/big_cheng/article/details/123441548.

Unicode

unicode 给地球上每一个字符(character) 分配一个整数, 这些整数的范围称为codespace(编码空间; [参考1] 2.4 Code Points and Characters). 空间里的每个整数称为一个code point(编码点).

在上世纪unicode 总共容纳了几万个字符, 当时用2个字节(uint16, 0~65535) 可以表示每个code point. 后来字符越来越多容纳不下, 为保持兼容, 增加一个uint16(即用一对uint16) 来表示超出范围的新字符. 这种编码形式称为UTF-16, 其中每个uint16(即2个字节) 称为其code unit(编码单位; [参考1] 2.5 Encoding Forms).

unicode 还有UTF-32UTF-8 两种编码形式. 前者固定用4个字节(定长) 来表示一个字符, 其编码单位(code unit)=4字节; 后者用1到4个字节(变长) 来表示一个字符, 其code unit=1字节.

unicode 目前(14.0.0) code point 的范围是0~0x10FFFF(1,114,111, 21比特). 每64K(即65536, uint16) 划分为一个plane(平面; [参考1] 2.8 Unicode Allocation), 0~16共有17个平面(65536*17=1,114,112). 其中平面0(即上世纪的code point 范围, 0x0000~0xFFFF) 称为BMP(Basic Multilingual Plane, 基本多语言平面), 大部分人大部分时候使用的字符应该都不会超出该平面.

BMP 里0xD800~0xDFFF code point 称为surrogate code([参考1] 2.9 Details of Allocation Figure 2-14. Allocation on the BMP), UTF-16 用来编码BMP 之外所有平面的字符(这些称为supplementary character, 辅助字符). 规则见[参考2] 3.9 Unicode Encoding Forms Table 3-5. UTF-16 Bit Distribution(另, [参考3]):

  • BMP 内的字符其编码 = code point 值
  • BMP 外的字符其code point = 000uuuuu xxxxxxxx xxxxxxxx(21比特有内容), 则其编码 = 110110wwwwxxxxxx 110111xxxxxxxxxx, 其中wwww = uuuuu - 1

举例, 平面2 的第一个字符U+20000 “????” 字:
code point:
000uuuuu xxxxxxxx xxxxxxxx
00000010 00000000 00000000
wwww = uuuuu - 1 = 00010 - 1 = 0001
编码:
110110wwwwxxxxxx 110111xxxxxxxxxx
1101100001000000 1101110000000000
55360 56320
0xD840 0xDC00 - 均是surrogate code(0xD800~0xDFFF).

如上, 对于1个辅助字符, UTF-16 编码成2个surrogate codes - 称为surrogate pair(代理对, [参考1] 2.5 Encoding Forms - UTF-16). 代理对的开始code unit 也称为high/leading surrogate, 结束code unit 也称为low/trailing surrogate.

一般仅UTF-16 需考虑surrogate 问题, 例如遇到孤儿surrogate code(不成对的), 可以替换为unicode 替换字符(0xFFFD) 或者丢弃等. 注意, 单个surrogate code 仅仅是一个code point 而已, 没有对应的unicode 字符.

Java

Java 设计于上世纪, 所以String 是以UTF-16 code unit 为单位, 即String = 一组char, char = 2个字节([参考4]), char 范围0~65535.

public final class String implements ...... {
    private final char value[];
    ......
}

通常的操作(包括下标) 都是针对这个char[], 当需要特殊处理code point 时有额外的方法.

        String s1 = "A????B", s2 = "AuD840uDC00B";
        // len=4, equal
        System.out.printf("len=%d, %sn", s1.length(),
                s1.equals(s2) ? "equal" : "not equal");

        char c = s1.charAt(1);
        System.out.println((int) c); // 55360

        int i = s1.codePointAt(1), j = s1.codePointAt(2);
        System.out.printf("0x%H, %dn", i, j); // 0x20000, 56320

        String subs = s1.substring(2);
        // "?B" len=2, [0] isLowSurrogate: true
        System.out.printf(""%s" len=%d, [0] isLowSurrogate: %bn", subs, subs.length(),
                Character.isLowSurrogate(subs.charAt(0)));

Go

Go 比较独特: 源代码只使用UTF-8; string 就是一组byte, 内部并没有预先拆成一个个rune 而是在运行时动态拆开.

	s := "AU00020000B"
	// len=6
	fmt.Printf("len=%dn", len(s))
	// [0] 0x41 [1] 0x20000 [5] 0x42
	for i, c := range s {
		fmt.Printf("[%d] 0x%X ", i, c)
	}
	fmt.Println()

可使用unicode/utf16 包来处理UTF-16.

Windows C

#include <windows.h>
#include <stdio.h>

int main()
{
    WCHAR * s = L"A????B";
    wprintf(L"len=%d, sizeof=%dn", wcslen(s), sizeof s); // len=4, sizeof=8
    s++;
    wprintf(L"high surrogate=%dn", (int)*s); // high surrogate=55360
    s++;
    wprintf(L"low surrogate=%dn", (int)*s); // low surrogate=56320
    return 0;
}

Windows 也是类似Java, 使用UTF-16(wide character) 来支持unicode([参考5]).

相关文章

mysql | Incorrect string value: ‘xE7) xE5xA4xB1…‘

参考

[1] https://www.unicode.org/versions/Unicode14.0.0/ch02.pdf
General Structure

[2] https://www.unicode.org/versions/Unicode14.0.0/ch03.pdf
Conformance

[3] https://unicode.org/faq/utf_bom.html#utf16-3
Q: What’s the algorithm to convert from UTF-16 to character codes?

[4] https://docs.oracle.com/javase/specs/jls/se17/html/jls-3.html#jls-3.10.4
Java Language Specification
Chapter 3. Lexical Structure

[5] https://docs.microsoft.com/en-us/windows/win32/intl/unicode

[6] https://docs.microsoft.com/zh-cn/windows/win32/learnwin32/working-with-strings
操作字符串

最后

以上就是爱听歌悟空为你收集整理的hello, unicode surrogate版权UnicodeJavaGoWindows C相关文章参考的全部内容,希望文章能够帮你解决hello, unicode surrogate版权UnicodeJavaGoWindows C相关文章参考所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部