当前位置:首页 > PHP

php实现punycode

2026-02-28 09:05:32PHP

PHP 实现 Punycode

Punycode 是一种用于将 Unicode 字符串转换为 ASCII 字符串的编码方式,常用于国际化域名(IDN)的处理。以下是几种在 PHP 中实现 Punycode 转换的方法。

使用内置函数 idn_to_asciiidn_to_utf8

PHP 提供了内置函数 idn_to_asciiidn_to_utf8,可以方便地进行 Punycode 编码和解码。这些函数需要 PHP 安装 intl 扩展。

// 编码为 Punycode
$domain = "例子.测试";
$punycode = idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
echo $punycode; // 输出: xn--fsq.xn--0zwm56d

// 解码为 Unicode
$original = idn_to_utf8($punycode, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
echo $original; // 输出: 例子.测试

使用第三方库

如果无法使用 intl 扩展,可以使用第三方库如 true/punycode

安装库:

composer require true/punycode

使用示例:

use True\Punycode;

$punycode = new Punycode();

// 编码为 Punycode
$encoded = $punycode->encode('例子.测试');
echo $encoded; // 输出: xn--fsq.xn--0zwm56d

// 解码为 Unicode
$decoded = $punycode->decode($encoded);
echo $decoded; // 输出: 例子.测试

手动实现 Punycode 算法

如果需要手动实现 Punycode 算法,可以参考以下简化代码(仅用于学习,实际项目中建议使用内置函数或第三方库)。

function punycode_encode($input) {
    $output = '';
    $n = 128;
    $delta = 0;
    $bias = 72;
    $basic_length = 0;

    // 处理基本字符
    for ($i = 0; $i < strlen($input); $i++) {
        if (ord($input[$i]) < 128) {
            $output .= $input[$i];
            $basic_length++;
        }
    }

    if ($basic_length > 0) {
        $output .= '-';
    }

    $h = $b = $basic_length;
    while ($h < strlen($input)) {
        $m = 0x10FFFF;
        for ($i = 0; $i < strlen($input); $i++) {
            $c = ord($input[$i]);
            if ($c >= $n && $c < $m) {
                $m = $c;
            }
        }

        $delta += ($m - $n) * ($h + 1);
        $n = $m;

        for ($i = 0; $i < strlen($input); $i++) {
            $c = ord($input[$i]);
            if ($c < $n) {
                $delta++;
            } elseif ($c == $n) {
                $q = $delta;
                for ($k = 36;; $k += 36) {
                    $t = ($k <= $bias) ? 1 : (($k >= $bias + 26) ? 26 : ($k - $bias));
                    if ($q < $t) break;
                    $output .= chr($t + ($q - $t) % (36 - $t) + 97);
                    $q = floor(($q - $t) / (36 - $t));
                }

                $output .= chr($q + 97);
                $bias = adapt($delta, $h + 1, $h == $b);
                $delta = 0;
                $h++;
            }
        }
        $delta++;
        $n++;
    }

    return 'xn--' . $output;
}

function adapt($delta, $numpoints, $firsttime) {
    $delta = $firsttime ? floor($delta / 700) : floor($delta / 2);
    $delta += floor($delta / $numpoints);
    $k = 0;
    while ($delta > 455) {
        $delta = floor($delta / 35);
        $k += 36;
    }
    return $k + floor(36 * $delta / ($delta + 38));
}

注意事项

  • 使用 idn_to_asciiidn_to_utf8 时,确保 intl 扩展已安装并启用。
  • 第三方库如 true/punycode 提供了更简单的接口,适合没有 intl 扩展的环境。
  • 手动实现 Punycode 算法较为复杂,建议仅在特殊需求时使用。

php实现punycode

标签: phppunycode
分享给朋友:

相关文章

php实现打印功能

php实现打印功能

PHP 实现打印功能的方法 PHP 可以通过多种方式实现打印功能,具体取决于打印的目标(如打印机、PDF、网页等)和需求(如直接打印、生成打印预览等)。以下是几种常见的实现方式: 使用 JavaSc…

php实现文件下载

php实现文件下载

PHP实现文件下载的方法 通过PHP实现文件下载功能,可以采用多种方式,以下是几种常见的实现方法: 使用header()函数强制下载 设置HTTP头信息,强制浏览器下载文件而非直接打开:…

php实现递归

php实现递归

递归的基本概念 递归是一种函数调用自身的技术,适用于解决可以分解为相同子问题的问题。在PHP中,递归需要明确的终止条件(基线条件),否则会导致无限循环。 递归实现阶乘 阶乘是经典的递归案例,n! =…

php实现websocket

php实现websocket

PHP 实现 WebSocket WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。PHP 可以通过多种方式实现 WebSocket 功能,以下是几种常见的方法: 使用 Rat…

php如何实现直播

php如何实现直播

实现直播功能的方法 PHP可以通过结合其他技术和工具来实现直播功能。以下是几种常见的方法: 使用流媒体服务器 配置流媒体服务器如Nginx-RTMP、Red5或Wowza。这些服务器支持RTM…

php实现上传

php实现上传

PHP 文件上传实现 HTML 表单设置 创建一个包含文件上传字段的 HTML 表单,确保表单的 enctype 属性设置为 multipart/form-data,这是文件上传必需的设置。 &l…