2013-01-14 16 views
7

मैं php में डोमेन यूआरएल जिसमें यूनानी डोमेन नाम = http की तरह अंतर्राष्ट्रीय डोमेन नाम प्रारूप में हो सकता है मान्य करने के लिए चाहते हैं मान्य करने के लिए: //παράδειγμα.δοκιμή उनकी किसी भी तरह से नियमित रूप से उपयोग कर इसे मान्य करने के लिए है अभिव्यक्ति?कैसे अंतर्राष्ट्रीय डोमेन नाम

+1

"मान्य" के रूप में "जाँच अगर यह DNS के लिए स्वीकार्य है" (विफलताओं काफी दुर्लभ हो जाएगा) या में "के रूप में जाँच करता है, तो यह वास्तव में DNS में मौजूद है" (विफलताओं आम हो सकता है, यादृच्छिक इनपुट दिया)। – tripleee

+0

मान्य क्या है? क्या यह कुछ वर्णों के बाद 'http: //' है, फिर कुछ वर्णों के बाद '.'' है? –

+0

मैं सिर्फ यह जांचना चाहता हूं कि DNS मान्य है या नहीं। क्या कोई रेगेक्स है जो यहां मेरी मदद कर सकता है। यूआरएल में जर्मन जैसी अन्य भाषाओं के पात्र हो सकते हैं। जैसे yahoo.com। मैं इस रेगेक्स का उपयोग कर रहा हूं लेकिन यह केवल अल्फान्यूमेरिक वर्णों के लिए काम नहीं करेगा।/^ [A-z \ घ] [a-z \ घ -] {0,62} $/i। मैं रेगेक्स कैसे बना सकता हूं जो अन्य भाषाओं के चरित्र को भी स्वीकार करता है, – user1969981

उत्तर

2

यह idn डोमेन हैं, मैं इसे पहले puny code संस्करण और validate डोमेन में परिवर्तित कर दूंगा।

लेकिन क्या तुम सच में

<?php 

$domain = 'παράδειγμα.gr'; 
$regex = '#^([\w-]+://?|www[\.])?([^\-\s\,\;\:\+\/\\\?\^\`\=\&\%\"\'\*\#\<\>]*)\.[a-z]{2,7}$#'; 
if (preg_match($regex, $domain)) { 
    echo "VALID"; 
} 

रेगुलर एक्सप्रेशन द्वारा एक मान्य करना लेकिन इस आप, आप गलत possitives में चलाते हैं क्योंकि यह एक IDN डोमेन मैं tryed मान्य करने के लिए मान्य करने के लिए है कि कोई अमान्य वर्ण हैं वास्तव में जटिल है अगर भीतर, लेकिन सूची पूरी नहीं हुई है।

बेहतर bevore परिवर्तित punny कोड

$regex = '#^([\w-]+://?|www[\.])?[a-z0-9]+[a-z0-9\-\.]*[a-z0-9]+\.[a-z]{2,7}$#'; 
if (preg_match($regex, idn_to_ascii($domain))) { 
    echo "VALID"; 
} 

करने और आप अतिरिक्त परीक्षण करना चाहते हैं, तो डोमेन कोशिश हल किया जा सकता है अगर:

$regex = '#^([\w-]+://?|www[\.])?[a-z0-9]+[a-z0-9\-\.]*[a-z0-9]+\.[a-z]{2,7}$#'; 
$punny_domain = idn_to_ascii($domain); 
if (preg_match($regex, $punny_domain)) { 
    if (gethostbyname($punny_domain) != $punny_domain) { 
     echo "VALID"; 
    } 
} 
1

यह एक तथाकथित IDN domain है। आईडीएन डोमेन का समर्थन करने वाले ग्राहक RFC 5890 में निर्दिष्ट आईडीएनए 2008 मानक का उपयोग करके इसे सामान्यीकृत करते हैं, फिर Punycode एन्कोडिंग का उपयोग करके शेष यूनिकोड वर्णों को प्रतिस्थापित करें जैसा कि RFC 3492 में DNS रिज़ॉल्यूशन प्रस्तुत करने से पहले परिभाषित किया गया है।

विनिर्देशन के अनुसार, यूटीएफ -8 वर्ण सेट में शाब्दिक रूप से प्रत्येक वर्ण एक आईडीएन डोमेन में उपयोग करने के लिए मान्य है, लेकिन प्रत्येक शीर्ष स्तर डोमेन प्राधिकरण यूनिकोड वर्णसेट के भीतर मान्य वर्णों को परिभाषित कर सकता है, इसलिए create and maintain a real regex करना मुश्किल होगा।

यदि आप अपने आवेदन में आईडीएन डोमेन स्वीकार करना चाहते हैं तो आपको आंतरिक रूप से एन्कोडेड संस्करण के साथ काम करना चाहिए। PHP extension intl एन और डिकोड करने के लिए IDN डोमेन नाम

echo idn_to_ascii('täst.de'); 

xn--tst-qla.de

एन्कोडिंग के बाद, डोमेन, किसी भी traditional regex check

सरल पारित करेंगे दो कार्यों लाता है सत्यापन:

$url = "http://example.com/"; 
if (preg_match('/^(http|https|ftp):\/\/([A-Z0-9][A-Z0-9_-]*(?:\.[A-Z0-9][A-Z0-9_-]*)+):?(\d+)?\/?/i', $url)) { 
    echo 'OK'; 
} else { 
    echo 'Invalid URL.'; 
} 

संपादित करें:

आप एक असली डीएनएस चाहते हैं तो आप उपयोग कर सकते हैं verfification dns_get_record (5 PHP) या gethostbyaddr

उदा

$domain = 'ελληνικά.idn.icann.org'; 
$idnDomain = idn_to_ascii($domain); 

if ($dnsResult = dns_get_record($idnDomain, DNS_ANY)) 
{ 
    echo $idnDomain , "\n"; 
    print_r($dnsResult); 
} 
else 
{ 
    echo "failed to lookup domain\n"; 
} 

परिणाम:

xn--hxargifdar.idn.icann.org 
Array 
(
    [0] => Array 
    (
     [host] => xn--hxargifdar.idn.icann.org 
     [class] => IN 
     [ttl] => 21456 
     [type] => A 
     [ip] => 199.7.85.10 
    ) 
    [1] => Array 
    (
     [host] => xn--hxargifdar.idn.icann.org 
     [class] => IN 
     [ttl] => 21600 
     [type] => AAAA 
     [ipv6] => 2620::2830:230:0:0:0:10 
    ) 
) 
+2

मुझे लगता है * मुझे आपके उत्तर में एक * महत्वपूर्ण * त्रुटि मिली। आप कहते हैं: 'विनिर्देशन के अनुसार, यूटीएफ -8 वर्ण सेट में शाब्दिक रूप से प्रत्येक वर्ण एक आईडीएन डोमेन' में उपयोग करने के लिए मान्य है (जब आप IDNA2008 और RFC5890 के बारे में बात करते हैं)। * कैसे * (मेरी समझ में), आईडीएनए 2008 अब 'आठ हजार वर्णों को अस्वीकार करता है जो वैध होने के लिए उपयोग किए जाते थे, जिसमें सभी अपरकेस वर्ण, पूर्ण/आधे-चौड़ाई वाले संस्करण, प्रतीकों और विराम चिह्न' (पहले आईडीएनए 2003 में अनुमति दी गई थी और फिलहाल अधिकांश कार्यान्वयन में काम करते हैं)। Http://www.unicode.org/faq/idn.html और http://tools.ietf.org/html/rfc5892 देखें। क्या मैंने इसे गलत तरीके से पढ़ा? – GitaarLAB

+1

@ गीता धन्यवाद, हाँ आप सही हैं। यह मेरे लिए नया है लेकिन पूरी तरह से समझ में आता है, क्योंकि डोमेन नाम केस असंवेदनशील होते हैं, और विराम चिह्न पात्र आरक्षित हो सकते हैं (उदा। 'डॉट' डोमेन डिलीमीटर,'? 'क्वेरी स्ट्रिंग डिलीमीटर आदि। –

2

आप अपने खुद के libirary बनाना चाहते हैं, तो आप अनुमति दी कोड पॉइंट्स की तालिका (IANA — Repository of IDN Practices, IDN Character Validation Guidance, IDNA Parameters) और यूनिकोड स्क्रिप्ट संपत्तियों की तालिका (उपयोग करने की आवश्यकता UNIDATA/Scripts.txt)।

जीमेल ने यूनिकोड कंसोर्टियम के "एच ighly Restricted" विनिर्देशन (Protecting Gmail in a global world) को अपनाया है। यूनिकोड स्क्रिप्ट्स के निम्नलिखित संमिश्रणों की अनुमति है।

  • एकल स्क्रिप्ट
  • लैटिन + हान + हीरागाना + काताकाना
  • लैटिन + हान + बोपोमोफो
  • लैटिन + हान + हंगुल

आप विशेष स्क्रिप्ट संपत्ति को attension भुगतान करना पड़ सकता मान (सामान्य, विरासत, अज्ञात) क्योंकि कुछ पात्रों में एकाधिक गुण या गलत गुण होते हैं।

उदाहरण के लिए, यू +30 99 (संयोजित कटकाना-हिरागाना आवाज ध्वनि ध्वनि) में दो प्रोविर्टीज ("कटाकाना" और "हिरगाना") हैं और पीसीआरई फ़ंक्शन इसे "विरासत" के रूप में वर्गीकृत करता है। एक और उदाहरण यू + एक्स 2 ए 708 है। यूथोह यू + 2 ए 708 की सही स्क्रिप्ट प्रॉपर्टी (यू + 30 सी 8 कटकाना लिटर टू और यू + 30 ई 2 कटकाना लिटर एमओ का संहिता) "कटाकाना" है, यूनिकोड विशिष्टता इसे "हान" के रूप में गलत वर्गीकृत करती है।

आपको IDN homograph attack पर विचार करने की आवश्यकता हो सकती है। Google क्रोम का IDN policythe blacklist chars को गोद लेता है।

मेरी सिफारिश Zend \ Validator \ होस्टनाम का उपयोग करना है। यह पुस्तकालय जापानी और चीनी के लिए the table of permitted code points का उपयोग करता है।

यदि आप सिम्फनी का उपयोग करते हैं, तो संस्करण के ऐप को 2.5 तक अपग्रेड करने पर विचार करें जो egulias/email-validatornd (Manual) को गोद लेता है। आपको अतिरिक्त सत्यापन की आवश्यकता है कि स्ट्रिंग अच्छी तरह से गठित बाइट अनुक्रम है या नहीं। विस्तार के लिए मेरे report ए> देखें।

एक्सएसएस और एसक्यूएल इंजेक्शन को न भूलें। निम्नलिखित पता वैध ईमेल पता आधारित RFC5322 है।

// From Japanese tutorial 
// http://blog.tokumaru.org/2013/11/xsssqlrfc5322.html 
"><script>alert('or/**/1=1#')</script>"@example.jp 

मुझे लगता है कि सत्यापन के लिए idn_to_ascii का उपयोग कर के बाद से idn_to_ascii लगभग सभी किरदारों से गुजरता के लिए संदिग्ध है।

for ($i = 0; $i < 0x110000; ++$i) { 
    $c = utf8_chr($i); 

    if ($c !== '' && false !== idn_to_ascii($c)) { 
     $number = strtoupper(dechex($i)); 
     $length = strlen($number); 

     if ($i < 0x10000) { 
      $number = str_repeat('0', 4 - $length).$number; 
     } 

     $idn = $c.'example.com'; 

     echo 'U+'.$number.' '; 
     echo ' '.$idn.' '. idn_to_ascii($idn); 
     echo PHP_EOL; 
    } 
} 

function utf8_chr($code_point) { 

    if ($code_point < 0 || 0x10FFFF < $code_point || (0xD800 <= $code_point && $code_point <= 0xDFFF)) { 
     return ''; 
    } 

    if ($code_point < 0x80) { 
     $hex[0] = $code_point; 
     $ret = chr($hex[0]); 
    } else if ($code_point < 0x800) { 
     $hex[0] = 0x1C0 | $code_point >> 6; 
     $hex[1] = 0x80 | $code_point & 0x3F; 
     $ret = chr($hex[0]).chr($hex[1]); 
    } else if ($code_point < 0x10000) { 
     $hex[0] = 0xE0 | $code_point >> 12; 
     $hex[1] = 0x80 | $code_point >> 6 & 0x3F; 
     $hex[2] = 0x80 | $code_point & 0x3F; 
     $ret = chr($hex[0]).chr($hex[1]).chr($hex[2]); 
    } else { 
     $hex[0] = 0xF0 | $code_point >> 18; 
     $hex[1] = 0x80 | $code_point >> 12 & 0x3F; 
     $hex[2] = 0x80 | $code_point >> 6 & 0x3F; 
     $hex[3] = 0x80 | $code_point & 0x3F; 
     $ret = chr($hex[0]).chr($hex[1]).chr($hex[2]).chr($hex[3]); 
    } 

    return $ret; 
} 

यदि आप यूनिकोड स्क्रिप्ट गुणों द्वारा डोमेन को प्रमाणित करना चाहते हैं, तो पीसीआरई फ़ंक्शंस का उपयोग करें।

निम्नलिखित कोड दिखाता है कि यूनिकोड स्क्रिप्ट संपत्ति का नाम कैसे प्राप्त करें। यदि आप जावास्क्रिप्ट में यूनिकोड स्क्रिप्ट पेपरोपर्टीज़ को धोना चाहते हैं, तो mathiasbynens/unicode-data का उपयोग करें।

function get_unicode_script_name($c) { 

    // http://php.net/manual/regexp.reference.unicode.php 
    $names = [ 
    'Arabic', 'Armenian', 'Avestan', 'Balinese', 'Bamum', 'Batak', 'Bengali', 
    'Bopomofo', 'Brahmi', 'Braille', 'Buginese', 'Buhid', 'Canadian_Aboriginal', 
    'Carian', 'Chakma', 'Cham', 'Cherokee', 'Common', 'Coptic', 'Cuneiform', 
    'Cypriot', 'Cyrillic', 'Deseret', 'Devanagari', 'Egyptian_Hieroglyphs', 
    'Ethiopic', 'Georgian', 'Glagolitic', 'Gothic', 'Greek', 'Gujarati', 
    'Gurmukhi', 'Han', 'Hangul', 'Hanunoo', 'Hebrew', 'Hiragana', 'Imperial_Aramaic', 
    'Inherited', 'Inscriptional_Pahlavi', 'Inscriptional_Parthian', 'Javanese', 
    'Kaithi', 'Kannada', 'Katakana', 'Kayah_Li', 'Kharoshthi', 'Khmer', 'Lao', 'Latin', 
    'Lepcha', 'Limbu', 'Linear_B', 'Lisu', 'Lycian', 'Lydian', 'Malayalam', 'Mandaic', 
    'Meetei_Mayek', 'Meroitic_Cursive', 'Meroitic_Hieroglyphs', 'Miao', 'Mongolian', 
    'Myanmar', 'New_Tai_Lue', 'Nko', 'Ogham', 'Old_Italic', 'Old_Persian', 
    'Old_South_Arabian', 'Old_Turkic', 'Ol_Chiki', 'Oriya', 'Osmanya', 'Phags_Pa', 
    'Phoenician', 'Rejang', 'Runic', 'Samaritan', 'Saurashtra', 'Sharada', 'Shavian', 
    'Sinhala', 'Sora_Sompeng', 'Sundanese', 'Syloti_Nagri', 'Syriac', 'Tagalog', 
    'Tagbanwa', 'Tai_Le', 'Tai_Tham', 'Tai_Viet', 'Takri', 'Tamil', 'Telugu', 'Thaana', 
    'Thai', 'Tibetan', 'Tifinagh', 'Ugaritic', 'Vai', 'Yi' 
    ]; 

    $ret = []; 

    foreach ($names as $name) { 

    $pattern = '/\p{'.$name.'}/u'; 

    if (preg_match($pattern, $c)) { 
     return $name; 
    } 
    } 

    return ''; 
} 
संबंधित मुद्दे