`
cnhawkwing
  • 浏览: 67036 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

punycode转换函数

阅读更多

<?
/*

Site  http://blog.cnhawk.org/
本程序 需要iconv 函数库的工作
*/
define("punycode_TMIN",1);
define("punycode_TMAX",26);
define("punycode_BASE",36);
define("punycode_INITIAL_N",128);
define("punycode_INITIAL_BIAS",72);
define("punycode_DAMP",700);
define("punycode_SKEW",38);
define("punycode_DELIMITER","-");
define("punycode_MAXINT",2147483647);

// 以下三个是encode编码时候的返回值
define("punycode_bad_input",-1);
define("punycode_big_output",-2);
define("punycode_overflow",-3);


//punycode转换函数 punycode编码
/*
输入的字符传不能有空格.
以.分割几段来进行处理
对中文全角字母不区分大小写
中文字符不能包含@#$%之类的字符
*/
//punycode 编码
function punycode_encode($input, $code="GBK")
{
 $input=trim($input);
 $input=str_replace("。",".",$input);
 $strarr=array();
 $strarr=explode(".",$input);
 $output="";
 for ($i=0;$i<count($strarr);$i++){
  $tmp_output=punycode_encode2($strarr[$i], $code);
  if(!$tmp_output || $tmp_output<0) return;

  if ($i!=count($strarr)-1) $tmp_output.=".";
  $output.=$tmp_output;
 }
 return $output;
}

//punycode 解码
function punycode_decode($input, $code="GBK")
{
 $input=trim($input);
 $strarr=array();
 $strarr=explode(".",$input);
 $output="";
 for ($i=0;$i<count($strarr);$i++){
  if (substr($strarr[$i],0,4)=="xn--"){
   $input=substr($strarr[$i],4);
   $outtmp=punycode_decode2($input, $code);

   if (!$outtmp || $outtmp<0)  return;

   $output.=$outtmp;
  }else{
   $output.=$strarr[$i];
  }
  if ($i!=count($strarr)-1) $output.=".";
 }//for
 return $output;
}

//主要的编码转换工作
function punycode_encode2($input, $code="GBK")
{
 //$input=str_replace(""," ",$input);//某些输入法的全角有问题导致不能用iconv转换为Unicode,替换为标准的全角空格
 $oldinput=$input;
 $input=iconv($code,"Unicode",$input);//将输入字符转换为Unicode.cnnic用GBK,GBK是GB2312的扩展.取代GBK的是GB18030
 $input=substr($input,2);//去掉前面的255和254
 
 $n=punycode_INITIAL_N;
 $delta=0;
 $out=0;
 $max_out=256;
 $bias=punycode_INITIAL_BIAS;
 $output="";
 $inputlen=strlen($input);
 $ar=array();//用一个数组来保存字的编码
 for ($i=0;$i<$inputlen;$i+=2){
  $tmpar=ord($input{$i+1})*256+ord($input{$i});
  if ($tmpar==32) break;//32为空格的Unicode,空格后不作处理(参考cnnic).输入是最好限制输入不能包含空格
  $ar[]=$tmpar;
 }
 $inputlen=count($ar);
 for ($i=0;$i<$inputlen;$i++){//将大写全角字符转为小写
  if ($ar[$i]>=65313 && $ar[$i]<=65338) $ar[$i]=$ar[$i]+32;
 }
 //$arr=array();
 for ($j=0;$j<$inputlen;$j++){
  if (punycode_isBasic($ar[$j])){
   if ($max_out-$out<2) return punycode_big_output;
   //$arr[]=$case_flags ? punycode_encode_basic($input{$j}, $case_flags{$j}) : ord($input{$j});
   $output.=$case_flags ? chr(punycode_encode_basic($ar[$j], $case_flags{$j})) : chr($ar[$j]);//不考虑大小写
   $out++;
  }
 }
 
 $h=$b=$out;
 if ($b>0) {
  $output.=punycode_DELIMITER;
  $out++;
 }
 
 while ($h<$inputlen){
  for ($m=punycode_MAXINT,$j=0;$j<$inputlen;$j++){
   if ($ar[$j]>=$n && $ar[$j]<$m) $m=$ar[$j];
  }
  
  if ($m-$n>(punycode_MAXINT-$delta)/($h+1)) return punycode_overflow;
  $delta+=($m-$n)*($h+1);
  $n=$m;
  
  for ($j=0;$j<$inputlen;$j++){
   if ($ar[$j]<$n){
    if (++$delta==0) return punycode_overflow;
   }
   
   if ($ar[$j]==$n){
    $q=$delta;
    for ($k=punycode_BASE; ;$k+=punycode_BASE){
     if ($out>=$max_out) return punycode_big_output;
     $t=$k<=$bias ? punycode_TMIN:($k>=($bias+punycode_TMAX) ? punycode_TMAX:($k-$bias));
     if ($q<$t) break;
     //$arr[]=punycode_encode_digit($t+($q-$t)%(punycode_BASE-$t),0);
     $output.=chr(punycode_encode_digit($t+($q-$t)%(punycode_BASE-$t),0));
     $out++;
     $q=(int)(($q-$t)/(punycode_BASE-$t));
    }
    
    //$arr[]=punycode_encode_digit($q,$case_flags && $case_flags{$j});
    //$output.=chr(punycode_encode_digit($q,$case_flags && $case_flags{$j}));
    $output.=chr(punycode_encode_digit($q,0));//忽略大小写(0输出小写字母,1输出大写字母)
    $out++;
    $bias=punycode_adapt($delta,$h+1,$h==$b);
    $delta=0;
    $h++;
   }
  }
  $delta++;
  $n++;
 }
 if (substr($output,-1,1)==punycode_DELIMITER) $output=substr($output,0,-1);
 if ($output!=$oldinput) $output="xn--".$output;
 return $output;
}

//编码的参数
function punycode_adapt($delta,$numpoints,$firsttime)
{
 if ($firsttime)
  $delta=(int)($delta/punycode_DAMP);
 else $delta=(int)($delta/2);
 
 $delta+=(int)($delta/$numpoints);
 
 for ($k=0;$delta>(int)(((punycode_BASE-punycode_TMIN)*punycode_TMAX)/2);$k+=punycode_BASE){
  $delta=(int)($delta/(punycode_BASE-punycode_TMIN));
 }
 return $k+(int)(((punycode_BASE-punycode_TMIN+1)*$delta)/($delta+punycode_SKEW));
}

//处理数字,大小写字母
function punycode_encode_basic($bcp,$flag)
{
 //if ($bcp-97<26) $bcp-=32;
 $bcp-=($bcp-97<26)<<5;
 return $bcp+((!$flag && ($bcp-65<26))<<5);
}

//判断数字是否是ansi字符,禁止 @#$%^ 之类的符号
function punycode_isBasic($c)
{
 return $c<128;
 //return $aa=(($c==45) || ($c>=48 && $c<=57) || ($c>=65 && $c<=90) || ($c>=97 && $c<=122));
}

//处理数字,大小写字母
function punycode_decode_digit($c)
{
 if (($c-48)<10) return ($c-22);
 if (($c-65)<26) return ($c-65);
 if (($c-97)<26) return ($c-97);
 return punycode_BASE;
}

//处理数字,大小写字母
function punycode_encode_digit($d,$flag)
{
 $s1=(int)($d<26);//0或1
 $s2=(int)($flag!=0);
 return $d+22+75*$s1-($s2<<5);
}

//主要的解码转换工作
function punycode_decode2($input, $code="GBK")
{
 $n=punycode_INITIAL_N;
 $out=0;
 $i=0;
 $max_out=256;
 $bias=punycode_INITIAL_BIAS;
 $inputlen=strlen($input);
 $outputa=array();
 
 $b=0;
 for ($j=0;$j<$inputlen;$j++) if ($input{$j}=="-") $b=$j;
 

 for ($j=0;$j<$b;$j++){
  /*不考虑大小写
  if (ord($input{$j})-65<26)
   $case_flags[$out]="1";
  else
   $case_flags[$out]="0"; 
  */
  if (ord($input{$j})>128) return -1;
  //$output.=$input{$j};
  $outputa[]=ord($input{$j});
  $out++;
 }


 for ($in=$b>0?$b+1:0;$in<$inputlen;$out++)
 {
  $oldi=$i;
  $w=1;
  for ($k=punycode_BASE; ;$k+=punycode_BASE){
   if ($in>=$inputlen) return -2;
   $digit=punycode_decode_digit(ord($input{$in++}));
   if ($digit>=punycode_BASE) return -3;
   if ($digit>(punycode_MAXINT-$i)/$w) return -4;
   $i=$i+$digit*$w;
   $t=$k<=$bias ? punycode_TMIN:($k>=($bias+punycode_TMAX) ? punycode_TMAX:($k-$bias));
   if ($digit<$t) break;
   if ($w>punycode_MAXINT/(punycode_BASE-$t)) return -5;
   $w=$w*(punycode_BASE-$t);
  }
  
  $bias=punycode_adapt($i-$oldi,$out+1,$oldi==0);
  if ($i/($out+1)>punycode_MAXINT-$n) return -6;
  $n+=(int)($i/($out+1));
  $i=$i%($out+1);
 
  
  if ($out>=$max_out) return -7;
  
/*不考虑大小写
  for ($q=0;$q<$out-$i;$i++) $case_flags[$i+1+$q]= $case_flags[$i+$q];
  
  if ($input[$in-1]-65<26)
   $case_flags[$i]='1';
  else
   $case_flags[$i]='0';
*/   
  for ($qq=0;$qq<($out-$i);$qq++) $outputa[($i+$out)-$i-$qq]=$outputa[($i+$out)-$i-$qq-1];
  
  $outputa[$i++]=$n;
 }
 
 $outputstr="";
 for ($i=0;$i<count($outputa);$i++){
  if ($outputa[$i]<128)
   $outputstr.=chr($outputa[$i]);
  else{
   $hx=dechex($outputa[$i]);
   $gaowei=substr($hx,2,2);
   $diwei=substr($hx,0,2);
   $tmp_output=chr(hexdec($gaowei)).chr(hexdec($diwei));
   $tmp_output=iconv("Unicode", $code, $tmp_output);
   $outputstr.=$tmp_output;
  }
 }
 return $outputstr;
}

?>

分享到:
评论

相关推荐

    IDN.rar_ punycode a_PunyCode_Punycode php_php punycode_转码

    在实际应用中,使用Punycode转换对于处理IDN非常重要,因为这使得全球用户可以使用他们本地语言的字符来访问网站,提高了互联网的可访问性和可用性。例如,一个包含中文字符的域名,在经过Punycode转换后,可以在...

    前端项目-punycode.zip

    punycode.js-master 是一个前端项目,专注于提供punycode转换功能。punycode是一种用于在互联网域名系统(DNS)中编码非ASCII字符的技术。它遵循了互联网标准RFC3492和RFC5891,确保了在JavaScript环境下对国际化...

    PHP实例开发源码—中文域名punycode转码工具.zip

    2. 可能有示例代码或者测试用例,演示如何调用这些函数进行域名的punycode转换。 3. 可能还包括了相关文档,解释了代码的工作原理以及如何在实际项目中应用。 学习这个实例可以帮助开发者深入理解punycode转换的...

    Laravel开发-laravel-punycode

    1. **Unicode到punycode转换**:此包提供了一个函数,可以将包含非ASCII字符的字符串转换为punycode形式。这在处理URL、邮件地址等需要在ASCII环境中使用的字符串时非常有用。 2. **punycode到Unicode转换**:反之...

    punycode编码.rar

    punycode通过一种转换机制,将非ASCII字符的Unicode编码转换成只包含ASCII字符的字符串,以便在DNS中进行传输和解析。 Punycode的主要原理是基于XN--标准,它是一种变长到定长的编码方法。首先,Unicode字符串被...

    易语言punycode编码

    - Unicode到UCS-4的转换函数 - 基数和偏移量计算函数 - 非ASCII码点的ASCII表示函数 - Base-36编码和解码函数 - 拼接和验证函数 通过学习和使用这份源码,开发者不仅可以理解punycode编码的工作原理,还能进一步...

    易语言Punycode编码系统源码

    为了解决这个问题,IETF(Internet Engineering Task Force)在RFC 3490中定义了一种叫做Punycode的编码机制,使得非ASCII字符可以转换为ASCII字符集内的等价表示。 Punycode的核心思想是将Unicode字符转换成ASCII...

    易语言源码易语言punycode编码源码.rar

    易语言punycode编码源码是实现了punycode转换功能的源代码,主要目的是帮助易语言开发者在处理URL或者网络数据时,能够对包含非英文字符的部分进行编码和解码。punycode的核心算法基于XN--标准,这个标准允许Unicode...

    易语言源码易语言Punycode编码系统源码.rar

    在互联网上,由于DNS系统只能处理ASCII字符,因此,非ASCII字符的域名需要通过Punycode转换才能正常工作。Punycode主要应用于Unicode字符集,尤其是非英文字符的转换,例如中文、日文、韩文等。 易语言Punycode编码...

    mysql url到domain的转化函数

    在MySQL数据库环境中,有时我们需要将URL转换为对应的域名,这对于数据分析、日志处理或网站统计等应用场景非常有用。本文将详细介绍一个名为`func_url2domain.sql`的SQL函数,它专门用于实现这一功能。 首先,`...

    易语言Punycode编码系统源码-易语言

    易语言Punycode编码系统源码是一种专为易语言设计的编码转换工具,主要用于处理国际化的域名系统(IDN)中的非ASCII字符。Punycode是一种算法,它能够将Unicode字符转换成ASCII字符串,使得这些包含特殊字符的域名在...

    if_dl.rar_If...

    7. **源代码组织**:punycode.c和if_dl.c分别实现了Punycode转换和if_dl接口的函数,而punycode.h提供了相应的函数原型和类型定义,遵循C语言的模块化编程原则。 这些知识对于理解网络协议栈、底层网络编程、以及在...

    易语言punycode编码源码-易语言

    punycode是一种转换方法,它将Unicode字符串转换为基本的ASCII字符串,以便在互联网协议中使用。在易语言这个编程环境中,punycode的实现可以帮助开发者处理中文域名等含有非英文字符的字符串。 易语言punycode编码...

    php自定义函数实现汉字转换utf8编码的方法

    此外,文章还提到了几个在线编码转换工具,这些工具可以帮助开发者在不同编码之间进行转换,包括UTF-8到其他编码的转换,以及Punycode、Base64等编码格式的处理。这些工具在开发过程中可以作为便捷的辅助,尤其是在...

    PHP实例开发源码—中文域名转码系统HTML5版.zip

    3. **Punycode转换**:Punycode是一种基于XN--标准的转换方法,用于将Unicode字符串转换为可由DNS系统识别的形式。在PHP中,可以使用`idn_to_ascii`和`idn_to_utf8`函数来进行Punycode与Unicode之间的转换。 4. **...

    [工具查询]MooPHP之网址转换成HEX编码小工具 v1.0_hex.zip

    2. **编码转换**:工具内部使用PHP的内置函数如`rawurlencode()`或`urlencode()`来实现URL到HEX的转换。这两个函数的区别在于对某些字符的处理,`rawurlencode()`会将所有非字母数字字符转码,而`urlencode()`则会...

    基于ASP的中文域名转码系统 php版.zip

    2. **Punycode扩展**:PHP可能需要安装如`idn_to_ascii`这样的扩展来实现Punycode转换。 3. **HTTP头处理**:设置正确的HTTP响应头,如`Content-Type`,以指示服务器发送的内容类型。 4. **PHP与数据库交互**:...

    cn-en.zip_域名_转码

    这个程序或库可能是用某种编程语言(如Python、JavaScript或C++等)编写的,它的功能是接收一个中文域名,然后使用Punycode或其他类似的方法将其转换为可识别的ASCII格式。 源码的实现通常包括以下步骤: 1. 分割...

    ASP源码—中文域名转码查询工具 v1.0版.zip

    2. 转码算法:使用特定的函数或方法实现Punycode编码,将中文字符转换为ASCII字符串。 3. 输出展示:转换后的Punycode域名以适合URL的形式显示给用户。 4. 错误处理:对无效输入或转码失败的情况进行处理,提供友好...

    glibc-libidn-2.5.tar.gz

    4. **IDNA(Internationalized Domain Name Algorithm)**:这是 IETF 提出的一套算法,用于处理 IDN 的转换,包括从 Unicode 到 Punycode 的转换以及反之。libidn 实现了 IDNA 标准,为开发者提供了一套接口来处理 ...

Global site tag (gtag.js) - Google Analytics