2016-05-13 3 views
2

Ну, я использую класс idna_convert PHP (http://idnaconv.net/index.html) для кодирования/декодирования доменных имен.Как проверить, является ли домен punycode или нет?

К сожалению, не похоже, чтобы интерфейс был проверен, является ли доменное имя уже punycode или нет.

Каков наилучший способ достичь этого? Было бы неплохо, если бы кто-нибудь мог опубликовать исходный код, как проверить, что домен является punycode или нет (с объяснением, потому что код idna_convert для меня не совсем понятен). Я уже знаю, как поймать исключение из idna_convert. :-)

Btw .: idna_convert генерирует исключение при попытке конвертировать доменное имя в punycode, который уже является punycode (см. https://github.com/phlylabs/idna-convert/blob/master/src/Punycode.php; строка 157). Более того, я не совсем понимаю, как работает их проверка.

+0

Может быть, попробуйте функцию php idn_to_utf8 и сравните вывод с imput? http://php.net/manual/en/function.idn-to-utf8.php –

+0

@PavelPetrov: Спасибо, эта функция выглядит интересной и намного лучше, чем ловить исключение. :-) – Andreas

+0

@Andreas, но это может привести к неправильному результату, потому что punycode не только конвертирует в unicode. Знаете, Othervise, idna_convert не понадобится. – Jehy

ответ

0

Простейший способ - просто преобразовать его в любом случае и проверить, равен ли результат ввода.

EDIT: Вы можете расширить класс Punycode с чеком, как это:

class PunycodeCheck extends Punycode 
{ 
    public function check_encoded($decoded) 
    { 
     $extract = self::byteLength(self::punycodePrefix); 
     $check_pref = $this->UnicodeTranscoder->utf8_ucs4array(self::punycodePrefix); 
     $check_deco = array_slice($decoded, 0, $extract); 
     if ($check_pref == $check_deco) 
      return true; 
     return false; 
    } 
} 
+0

Это хорошее предложение, но, к сожалению, оно не работает, потому что idna_convert генерирует исключение, когда домен уже punycode и вы пытаетесь его закодировать. См. Https://github.com/phlylabs/idna-convert/blob/master/src/Punycode.php (строка 157). – Andreas

+0

@ Аndreas затем просто поймать это исключение и проверить текст исключения - и вы в порядке! – Jehy

+0

Да, но я не думаю, что это действительно действительное использование ... Я думаю, что имеет смысл (и гораздо более прямолинейно) сначала проверить, если домен должен быть закодирован для punycode или если он уже , Поэтому я знаю, что устранение исключения - это способ решить проблему, но мне это не очень нравится ... – Andreas

0

Единственным исключением, что метод encode() бросает, когда домен уже Punycode. Таким образом, вы можете сделать следующее:

try { 
    $punycode->encode($decoded); 
} catch (\InvalidArgumentException $e) { 
    //do whatever is needed when already punycode 
    //or do nothing 
} 

Однако это обходное решение.

+0

Согласен, но, на мой взгляд, было бы намного лучше проверить, если домен уже punycode или нет. Ловить InvalidArgumentException кажется скорее ... ну, грязным. – Andreas

+0

Я согласен с этим, это только первое, что пришло в голову, чтобы решить проблему. –

0

Это зависит от того, что именно вы хотите.

Как первая базовая проверка, проверьте, содержит ли доменное имя только символы ASCII. Если да, то домен «уже punycode», в том смысле, что он не может быть далее преобразован. Для проверки того, содержит ли строка только символы ASCII, см. Determine if UTF-8 text is all ASCII?.

Если вы хотите проверить, находится ли домен в форме IDN, разделите домен на точках . и проверьте, начинается ли какая-либо подстрока с xn--.

Если в дополнение к этому вы хотите проверить, является ли домен IDN и действителен, просто попробуйте его декодировать с помощью функции декодирования библиотеки.