简介
(一)码元(Code Unit)
-
码元是指在字符编码中用于表示字符的最小基本单位。它是编码系统中最小的数据单位,在不同的编码系统中,码元的定义和长度可能不同。
-
在 UTF-16 中,码元是 16 位的单元。字符可以由一个或两个 16 位的码元组成。一个码元表示一个基本的 Unicode 字符或一个代理对(surrogate pair)的一部分。
-
在 UTF-8 中,码元是 8 位(一个字节)。UTF-8 编码的字符可以使用一个或多个码元(字节)来表示。
(二)码点(Code Point)
-
码点是字符集中的每一个字符的唯一标识符,通常是一个整数。它代表了字符集中的具体字符,无论该字符的编码方式如何。码点不直接与具体的编码格式绑定,而是一个抽象的概念。
-
在 Unicode 中,码点是一个范围从 U+0000 到 U+10FFFF 的整数。例如,字符 "A" 的 Unicode 码点是 U+0041,字符 "你" 的 Unicode 码点是 U+4F60。
-
码点在编码过程中被转换成具体的码元(如 UTF-8、UTF-16 等),这些编码方案用不同的字节表示相同的码点。
用法
1. 获取 ‘码点’ 对应的码点值:str.codePointAt(index)
const str = '𠮷a';
// 获取第一个字符 '𠮷' 的点码
const codePoint1 = str.codePointAt(0);
console.log(codePoint1); // Output: 134071
// 获取第二个字符 'a' 的点码
const codePoint2 = str.codePointAt(1);
console.log(codePoint2); // Output: 97 (ASCII 码为 'a')
2. ‘码点’ 转字符:String.fromCodePoint(码点值)
// 将单个点码转换成字符
// 多个点码合并转换成字符使用 逗号 传入
const char1 = String.fromCodePoint(134071);
console.log(char1); // Output: '𠮷'
注意:获取字符串长度时其实是获取他的码元
案例
const text = "1😊2😊😊😊";
// 获取字符串码点的长度
String.prototype.pointLength = function () {
// 记录当前的下标
let len = 0;
for (let i = 0; i < text.length; ) {
len++;
// 判断当前占位,使用字符串.codePointAt(下标)方法,获取当前的码点对应的数字
let point = text.codePointAt(i);
i += point > 65535 ? 2 : 1;
}
return len;
};
// 根据码点的下标获取字符
String.prototype.pointAt = function (index) {
// 记录当前码点
let curIndex = 0;
for (let i = 0; i < text.length; ) {
// 判断当前码点与传入的下标是否一致
if (curIndex === index) {
// 获取码点的数字
let point = text.codePointAt(i);
// 码点转字符 使用String.fromCodePoint(码点值)
return String.fromCodePoint(point);
}
curIndex++;
// 获取码点的数字
let point = text.codePointAt(i);
i += point > 65535 ? 2 : 1;
}
};
// 截取
String.prototype.poinSlice = function (start, end) {
let result = "";
let len = text.pointLength();
// 循环所有的码点
for (let i = start; i < len && i < end; i++) {
result += text.pointAt(i);
}
return result;
};
console.log("码点数量", text.pointLength());
console.log("下标获取", text.pointAt(0));
console.log("下标获取", text.pointAt(1));
console.log("截取", text.poinSlice(1, 3));
总结
- 码点 是字符在字符集中的唯一标识符,是一个抽象的概念。
- 码元 是在特定编码格式中实际使用的数据单位,用来表示码点。
- 发现一个emoji表情占用2个码点,一个码点可以占用一个或多个码元
- 每个字符占用 16位 码元
- 一个码元占用 0-2^16次方 = 0-65535,转16 进制 0Xffff
- 生僻字、emoji标签需要占用两个码元,0-2^23次方