mirror of
				https://github.com/ShaYmez/FreeSTAR-Status-Engine.git
				synced 2025-11-03 20:20:20 -05:00 
			
		
		
		
	This external library adds functions to encode and decode email addresses using extended utf-8 character sets. Example examlpe@bånnibøtta.no The library is written as simple functions rather than a class. Original code at https://github.com/IgorVBelousov/php_idn
		
			
				
	
	
		
			321 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			321 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * Finds the character code for a UTF-8 character: like ord() but for UTF-8.
 | 
						|
 *
 | 
						|
 * @author Nicolas Thouvenin <nthouvenin@gmail.com>
 | 
						|
 * @copyright 2008 Nicolas Thouvenin
 | 
						|
 * @license http://opensource.org/licenses/LGPL-2.1 LGPL v2.1
 | 
						|
 */
 | 
						|
function ordUTF8($c, $index = 0, &$bytes = null)
 | 
						|
  {
 | 
						|
    $len = strlen($c);
 | 
						|
    $bytes = 0;
 | 
						|
    if ($index >= $len)
 | 
						|
    return false;
 | 
						|
    $h = ord($c{$index});
 | 
						|
    if ($h <= 0x7F) {
 | 
						|
    $bytes = 1;
 | 
						|
    return $h;
 | 
						|
    }
 | 
						|
    else if ($h < 0xC2)
 | 
						|
    return false;
 | 
						|
    else if ($h <= 0xDF && $index < $len - 1) {
 | 
						|
    $bytes = 2;
 | 
						|
    return ($h & 0x1F) << 6 | (ord($c{$index + 1}) & 0x3F);
 | 
						|
    }
 | 
						|
    else if ($h <= 0xEF && $index < $len - 2) {
 | 
						|
    $bytes = 3;
 | 
						|
    return ($h & 0x0F) << 12 | (ord($c{$index + 1}) & 0x3F) << 6
 | 
						|
    | (ord($c{$index + 2}) & 0x3F);
 | 
						|
    }
 | 
						|
    else if ($h <= 0xF4 && $index < $len - 3) {
 | 
						|
    $bytes = 4;
 | 
						|
    return ($h & 0x0F) << 18 | (ord($c{$index + 1}) & 0x3F) << 12
 | 
						|
    | (ord($c{$index + 2}) & 0x3F) << 6
 | 
						|
    | (ord($c{$index + 3}) & 0x3F);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
/**
 | 
						|
 * Encode UTF-8 domain name to IDN Punycode
 | 
						|
 *
 | 
						|
 * @param string $value Domain name
 | 
						|
 * @return string Encoded Domain name
 | 
						|
 *
 | 
						|
 * @author Igor V Belousov <igor@belousovv.ru>
 | 
						|
 * @copyright 2013, 2015 Igor V Belousov
 | 
						|
 * @license http://opensource.org/licenses/LGPL-2.1 LGPL v2.1
 | 
						|
 * @link http://belousovv.ru/myscript/phpIDN
 | 
						|
 */
 | 
						|
function EncodePunycodeIDN( $value )
 | 
						|
  {
 | 
						|
    if ( function_exists( 'idn_to_ascii' ) ) {
 | 
						|
      return idn_to_ascii( $value );
 | 
						|
    }
 | 
						|
 | 
						|
    /* search subdomains */
 | 
						|
    $sub_domain = explode( '.', $value );
 | 
						|
    if ( count( $sub_domain ) > 1 ) {
 | 
						|
      $sub_result = '';
 | 
						|
      foreach ( $sub_domain as $sub_value ) {
 | 
						|
        $sub_result .= '.' . EncodePunycodeIDN( $sub_value );
 | 
						|
      }
 | 
						|
      return substr( $sub_result, 1 );
 | 
						|
    }
 | 
						|
 | 
						|
    /* http://tools.ietf.org/html/rfc3492#section-6.3 */
 | 
						|
    $n      = 0x80;
 | 
						|
    $delta  = 0;
 | 
						|
    $bias   = 72;
 | 
						|
    $output = array();
 | 
						|
 | 
						|
    $input  = array();
 | 
						|
    $str    = $value;
 | 
						|
    while ( mb_strlen( $str , 'UTF-8' ) > 0 )
 | 
						|
      {
 | 
						|
        array_push( $input, mb_substr( $str, 0, 1, 'UTF-8' ) );
 | 
						|
        $str = (version_compare(PHP_VERSION, '5.4.8','<'))?mb_substr( $str, 1, mb_strlen($str, 'UTF-8') , 'UTF-8' ):mb_substr( $str, 1, null, 'UTF-8' );
 | 
						|
      }
 | 
						|
 | 
						|
    /* basic symbols */
 | 
						|
    $basic = preg_grep( '/[\x00-\x7f]/', $input );
 | 
						|
    $b = $basic;
 | 
						|
 | 
						|
    if ( $b == $input )
 | 
						|
      {
 | 
						|
        return $value;
 | 
						|
      }
 | 
						|
    $b = count( $b );
 | 
						|
    if ( $b > 0 ) {
 | 
						|
      $output = $basic;
 | 
						|
      /* add delimeter */
 | 
						|
      $output[] = '-';
 | 
						|
    }
 | 
						|
    unset($basic);
 | 
						|
    /* add prefix */
 | 
						|
    array_unshift( $output, 'xn--' );
 | 
						|
 | 
						|
    $input_len = count( $input );
 | 
						|
    $h = $b;
 | 
						|
 | 
						|
    $ord_input = array();
 | 
						|
 | 
						|
    while ( $h < $input_len ) {
 | 
						|
      $m = 0x10FFFF;
 | 
						|
      for ( $i = 0; $i < $input_len; ++$i )
 | 
						|
        {
 | 
						|
          $ord_input[ $i ] = ordUtf8( $input[ $i ] );
 | 
						|
          if ( ( $ord_input[ $i ] >= $n ) && ( $ord_input[ $i ] < $m ) )
 | 
						|
            {
 | 
						|
              $m = $ord_input[ $i ];
 | 
						|
            }
 | 
						|
        }
 | 
						|
      if ( ( $m - $n ) > ( 0x10FFFF / ( $h + 1 ) ) )
 | 
						|
        {
 | 
						|
          return $value;
 | 
						|
        }
 | 
						|
      $delta += ( $m - $n ) * ( $h + 1 );
 | 
						|
      $n = $m;
 | 
						|
 | 
						|
      for ( $i = 0; $i < $input_len; ++$i )
 | 
						|
        {
 | 
						|
          $c = $ord_input[ $i ];
 | 
						|
          if ( $c < $n )
 | 
						|
            {
 | 
						|
              ++$delta;
 | 
						|
              if ( $delta == 0 )
 | 
						|
                {
 | 
						|
                  return $value;
 | 
						|
                }
 | 
						|
            }
 | 
						|
          if ( $c == $n )
 | 
						|
            {
 | 
						|
              $q = $delta;
 | 
						|
              for ( $k = 36;; $k += 36 )
 | 
						|
                {
 | 
						|
                  if ( $k <= $bias )
 | 
						|
                    {
 | 
						|
                      $t = 1;
 | 
						|
                    }
 | 
						|
                  elseif ( $k >= ( $bias + 26 ) )
 | 
						|
                    {
 | 
						|
                      $t = 26;
 | 
						|
                    }
 | 
						|
                  else
 | 
						|
                    {
 | 
						|
                      $t = $k - $bias;
 | 
						|
                    }
 | 
						|
                  if ( $q < $t )
 | 
						|
                    {
 | 
						|
                      break;
 | 
						|
                    }
 | 
						|
                    $tmp_int = $t + ( $q - $t ) % ( 36 - $t );
 | 
						|
                  $output[] = chr( ( $tmp_int + 22 + 75 * ( $tmp_int < 26 ) ) );
 | 
						|
                  $q = ( $q - $t ) / ( 36 - $t );
 | 
						|
                }
 | 
						|
 | 
						|
              $output[] = chr( ( $q + 22 + 75 * ( $q < 26 ) ) );
 | 
						|
              /* http://tools.ietf.org/html/rfc3492#section-6.1 */
 | 
						|
              $delta = ( $h == $b ) ? $delta / 700 : $delta>>1;
 | 
						|
 | 
						|
              $delta += intval( $delta / ( $h + 1 ) );
 | 
						|
 | 
						|
              $k2 = 0;
 | 
						|
              while ( $delta > 455 )
 | 
						|
                {
 | 
						|
                  $delta /= 35;
 | 
						|
                  $k2 += 36;
 | 
						|
                }
 | 
						|
              $bias = intval( $k2 + 36 * $delta / ( $delta + 38 ) );
 | 
						|
              /* end section-6.1 */
 | 
						|
              $delta = 0;
 | 
						|
              ++$h;
 | 
						|
            }
 | 
						|
        }
 | 
						|
      ++$delta;
 | 
						|
      ++$n;
 | 
						|
    }
 | 
						|
    return implode( '', $output );
 | 
						|
  }
 | 
						|
 | 
						|
/**
 | 
						|
 * Decode IDN Punycode to UTF-8 domain name
 | 
						|
 *
 | 
						|
 * @param string $value Punycode
 | 
						|
 * @return string Domain name in UTF-8 charset
 | 
						|
 *
 | 
						|
 * @author Igor V Belousov <igor@belousovv.ru>
 | 
						|
 * @copyright 2013, 2015 Igor V Belousov
 | 
						|
 * @license http://opensource.org/licenses/LGPL-2.1 LGPL v2.1
 | 
						|
 * @link http://belousovv.ru/myscript/phpIDN
 | 
						|
 */
 | 
						|
function DecodePunycodeIDN( $value )
 | 
						|
  {
 | 
						|
    if ( function_exists( 'idn_to_utf8' ) ) {
 | 
						|
      return idn_to_utf8( $value );
 | 
						|
    }
 | 
						|
 | 
						|
    /* search subdomains */
 | 
						|
    $sub_domain = explode( '.', $value );
 | 
						|
    if ( count( $sub_domain ) > 1 ) {
 | 
						|
      $sub_result = '';
 | 
						|
      foreach ( $sub_domain as $sub_value ) {
 | 
						|
        $sub_result .= '.' . DecodePunycodeIDN( $sub_value );
 | 
						|
      }
 | 
						|
      return substr( $sub_result, 1 );
 | 
						|
    }
 | 
						|
 | 
						|
    /* search prefix */
 | 
						|
    if ( substr( $value, 0, 4 ) != 'xn--' )
 | 
						|
      {
 | 
						|
        return $value;
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
        $bad_input = $value;
 | 
						|
        $value = substr( $value, 4 );
 | 
						|
      }
 | 
						|
 | 
						|
    $n      = 0x80;
 | 
						|
    $i      = 0;
 | 
						|
    $bias   = 72;
 | 
						|
    $output = array();
 | 
						|
 | 
						|
    /* search delimeter */
 | 
						|
    $d = strrpos( $value, '-' );
 | 
						|
 | 
						|
    if ( $d > 0 ) {
 | 
						|
      for ( $j = 0; $j < $d; ++$j) {
 | 
						|
        $c = $value[ $j ];
 | 
						|
        $output[] = $c;
 | 
						|
        if ( $c > 0x7F )
 | 
						|
          {
 | 
						|
            return $bad_input;
 | 
						|
          }
 | 
						|
      }
 | 
						|
      ++$d;
 | 
						|
    } else {
 | 
						|
      $d = 0;
 | 
						|
    }
 | 
						|
 | 
						|
    while ($d < strlen( $value ) )
 | 
						|
      {
 | 
						|
        $old_i = $i;
 | 
						|
        $w = 1;
 | 
						|
 | 
						|
        for ($k = 36;; $k += 36)
 | 
						|
          {
 | 
						|
            if ( $d == strlen( $value ) )
 | 
						|
              {
 | 
						|
                return $bad_input;
 | 
						|
              }
 | 
						|
            $c = $value[ $d++ ];
 | 
						|
            $c = ord( $c );
 | 
						|
 | 
						|
            $digit = ( $c - 48 < 10 ) ? $c - 22 :
 | 
						|
              (
 | 
						|
                ( $c - 65 < 26 ) ? $c - 65 :
 | 
						|
                  (
 | 
						|
                    ( $c - 97 < 26 ) ? $c - 97 : 36
 | 
						|
                  )
 | 
						|
              );
 | 
						|
            if ( $digit > ( 0x10FFFF - $i ) / $w )
 | 
						|
              {
 | 
						|
                return $bad_input;
 | 
						|
              }
 | 
						|
            $i += $digit * $w;
 | 
						|
 | 
						|
            if ( $k <= $bias )
 | 
						|
              {
 | 
						|
                $t = 1;
 | 
						|
              }
 | 
						|
            elseif ( $k >= $bias + 26 )
 | 
						|
              {
 | 
						|
                $t = 26;
 | 
						|
              }
 | 
						|
            else
 | 
						|
              {
 | 
						|
                $t = $k - $bias;
 | 
						|
              }
 | 
						|
            if ( $digit < $t ) {
 | 
						|
                break;
 | 
						|
              }
 | 
						|
 | 
						|
            $w *= 36 - $t;
 | 
						|
 | 
						|
          }
 | 
						|
 | 
						|
        $delta = $i - $old_i;
 | 
						|
 | 
						|
        /* http://tools.ietf.org/html/rfc3492#section-6.1 */
 | 
						|
        $delta = ( $old_i == 0 ) ? $delta/700 : $delta>>1;
 | 
						|
 | 
						|
        $count_output_plus_one = count( $output ) + 1;
 | 
						|
        $delta += intval( $delta / $count_output_plus_one );
 | 
						|
 | 
						|
        $k2 = 0;
 | 
						|
        while ( $delta > 455 )
 | 
						|
          {
 | 
						|
            $delta /= 35;
 | 
						|
            $k2 += 36;
 | 
						|
          }
 | 
						|
        $bias = intval( $k2 + 36  * $delta / ( $delta + 38 ) );
 | 
						|
        /* end section-6.1 */
 | 
						|
        if ( $i / $count_output_plus_one > 0x10FFFF - $n )
 | 
						|
          {
 | 
						|
            return $bad_input;
 | 
						|
          }
 | 
						|
        $n += intval( $i / $count_output_plus_one );
 | 
						|
        $i %= $count_output_plus_one;
 | 
						|
        array_splice( $output, $i, 0,
 | 
						|
            html_entity_decode( '&#' . $n . ';', ENT_NOQUOTES, 'UTF-8' )
 | 
						|
         );
 | 
						|
        ++$i;
 | 
						|
      }
 | 
						|
 | 
						|
    return implode( '', $output );
 | 
						|
  }
 | 
						|
 |