X

曜彤.手记

随手写写,关于互联网技术、产品与创业

UCS-2 编码的妙用


我们在日常的开发当中经常会碰到诸如 UTF-8、UTF-16 等字符编码方式,其实这些字符编码方式都是 Unicode 编码的一种实现方式。而今天我们的主角就是Unicode 编码的另一种实现方式 - “UCS-2” 编码。借助于 “UCS-2” 编码,我们可以实现一些相对“特殊”的需求。

在介绍 “UCS-2” 之前,我们先来复习一下 Unicode 编码的相关知识。Unicode 编码是一种可以容纳全世界所有语言文字的编码方案。Unicode 使用一个确定的名字和一个叫做“码位”的十六进制数来定义一个字符。例如字符 “A” 对应的 Unicode 码位为 0x0041(十进制整数为65)的码位。而实际上 Unicode 编码的码位从 u0000(0x0000)到 u007F(0x007F)与 ASCII 完全一致。

Unicode 的码空间范围从 u0000(0x0000)到 u10FFFF(0x10FFFF),共有“1,112,064”个码位可用来映射字符. 而其中码位从 u0000 至 uFFFF 的范围内包含了最常用的字符,这一部分被称为基本多语言平面(Basic Multilingual Plane),缩写为 BMP。处于其他范围的码位则称为辅助平面(Supplementary Planes)。

UCS-2 英文全称为 “2-byte Universal Character Set”,而相对 UTF-8(变长编码)不同,它是一种定长的编码方式,UCS-2 仅仅简单的使用一个16位码元来表示码位,也就是说它可以表示 Unicode 编码从 u0000 到 uFFFF 码位范围内的所有字符。但请记住,UCS-2 只是一种 Unicode 编码的具体实现方式。

那么,我们可以拿 “UCS-2” 编码来做些什么呢?因为 “UCS-2” 在码位范围 u0000 到 uFFFF 范围内的编码与 Unicode 的码位完全一致,因此我们用这一特性来进行对字符的“语言识别”。通过判断某一字符的 UCS-2 编码的码位值(16进制值)其大小,可以判断该字符是属于那一语言或语系。比如汉语的 USC-2 编码码位范围为 u4E00(0x4E00)到 u9FFF(0x9FFF),其他语系也以此类推拥有其对应的码位范围。

下面给出基于 PHP的实现代码:(此段代码会自动分析用户输入字符串内的所有字符的所属语言体系)

class Util {
    public static function charAnaylze($str) {   
        // 转换成 UCS-2 定长编码;
        $str = iconv('UTF-8', 'UCS-2', $str);

        // 获取字符串总长度;
        $strLen = strlen($str);

        $tempStr = '';
        $resultArr = array();

        // 每次处理一个字符;
        for ($i = 0; $i < $strLen - 1; $i = $i + 2) {
            $lowByte = $str[$i];
            $highByte = $str[$i + 1];

            // 按位转换并填充;
            $lowByteEncoded = str_pad(base_convert(ord($lowByte), 10, 16), 2, 0, STR_PAD_LEFT);
            $highByteEncoded = str_pad(base_convert(ord($highByte), 10, 16), 2, 0, STR_PAD_LEFT);
            $hexStr = $lowByteEncoded . $highByteEncoded;
            $value = hexdec($hexStr);

            // 创建临时字符;
            $tempStr = iconv('UTF-8', 'UCS-2', "A");
            $tempStr[0] = $lowByte;
            $tempStr[1] = $highByte;

            // 编码;
            $char = iconv('UCS-2', 'UTF-8', $tempStr);

            if($value >= 65 && $value <= 122) {
                // Latin 字母;
                $resultArr['Latin字母'][] = $char;
            }

            if($value >= 48 && $value <= 57) {
                // Latin 数字;
                $resultArr['Latin数字'][] = $char;
            }

            if(($value >= 33 && $value <= 47) || ($value >= 58 && $value <= 64)) {
                // Latin 符号;
                $resultArr['Latin符号'][] = $char;
            }

            if(($value >= 1536 && $value <= 1791)) {
                // 阿拉伯语;
                $resultArr['阿拉伯语'][] = $char;
            }

            if(($value >= 19968 && $value <= 40959)) {
                // 汉字;
                $resultArr['汉字字符'][] = $char;
            }
        }

        return $resultArr;
    }
}


这是文章底线,下面是评论
  暂无评论,欢迎勾搭 :)